#!/bin/bash
#-------------------------------------------------------------------------------------------
#go.sh 是一个 饥荒联机版 shell脚本
#-------------------------------------------------------------------------------------------


#-------------------------------------------------------------------------------------------
# 脚本历史更新内容
#-------------------------------------------------------------------------------------------
#欲醉无由 2016.11.12  > 创建脚本 初步支持 Ubuntu 环境
#小草哥哥 2020.02.16  > 增加 CentOS 环境     
#小草哥哥 2020.12.03  > 1. 推出公测服务器版本（由于降级要重装已取消该功能） 2. 增加查看服务器版本			
#小草哥哥 2021.09.12  > 1. 面板重新排版 2. 增加 x64 x32 启动模式 3. 修复更新bug 4. 增加退出脚本操作
#			5. 调整关闭服务器无输入按回车返回脚本主目录 6. 为所有函数增加注释
#小草哥哥 2021.09.14  > 1. 修复 CentOS 系统动态库遇到的 libcurl-gnutls.so.4 问题
#小草哥哥 2021.09.19  > 1. 增加开启服务器输入‘quit’返回主菜单
#小草哥哥 2021.09.29  > 1. 增加 Arch 环境
#小草哥哥 2022.01.09  > 1. 增加启动主世界自动更新mod（v1、v2） 需配合（dedicated_server_mods_setup.lua）
#           v1 版本 mod 依旧存放在 'mods' 文件夹内，v2 版本 mod 存放在 ‘v2mods’ 文件夹内（与mods文件夹同级）
#           主世界与洞穴世界共用 ‘v2mods’ 文件夹！所以只需要主世界更新即可，第一次启动不会加载v2 mods ，需主世界
#           在正常启动一段时间后，正常加载v1 mods，服务器才会额外加在v2 版本mods ，待加载完直接重新启动服务器即可
#小草哥哥 2022.02.01  > 1. 注释忽略主服务器模组更新选项 -skip_update_server_mods  2. 模组管理增加更新选项
#            3. 增加主页模组状态显示
#小草哥哥 2022.10.23  > 1. 重构脚本 2. 增加游戏自动更新 3. 增加了脚本自动更新 4. 重写自动Mod更新 
#			5. 加入公测版本	6. 优化关服排版 7. 增加一键关服 8. 部分工具移至控制面板 9. 增加 Debian 环境
#			10. 游戏路径和存档路径统一存放在 SteamGameApp下 11. 增加config配置文件 12. 增加 .dstconf 配置文件夹
#			13. 增加 version 更新官方版本文件 14. 增加 newshell 脚本更新检测文件 15. steamcmd 移至 .steamcmd
#			16. 部分代码参考群成员诚徒(1549737287@qq.com)的脚本改进
#小草哥哥 2022.10.25  > 1. 优化关闭服务器UI （根据服务器名称进行分类） 2. 增加开服自动添加模组ID到更新队列
#小草哥哥 2022.10.28  > 1. 优化关闭服务器UI （PID加长，增加回车检测） 2. 增加公测通道检测，公测通道关闭无法启用测
#			试服务器（脚本不定期更新公测码，参考脚本配置文件）3. 修复5.0版 无法添加自己token的bug
#小草哥哥 2022.11.01  > 1. 修复会清空脚本的Bug，增加判断逻辑 2. 增加安装curl命令，避免最小安装无法检测更新
#小草哥哥 2022.11.04  > 1. 更新游戏版本验证方式增加逻辑判断
#小草哥哥 2022.11.09  > 1. 修复 debian ubuntu 优先安装32位库被卸载的bug
#小草哥哥 2022.11.15  > 1. 增加检测共享库函数 2. 公测版本增加时间戳验证（不验证时间导致正式版和公测版一致不会主动更新）
#			3. 优化关闭服务器UI世界名称显示Bug
#小草哥哥 2022.11.21  > 1. 修复时间标签Bug 2. 修复公测版Key的Bug 3. 增加手动更新正式版 4. 增加手动更新公测版
#			5. 启动服务器函数优化 6. 一键关服玩家在线确认 7. 增加快速存档 8. 增加快速回档 9. 增加快速公告
#			10. 增加在线玩家检测 11. 关闭服务器更改为查看服务器 12. 优化选择逻辑 
#小草哥哥 2023.01.01  > 1. 服务器更新方式更换（Klei官网真的NT） 2. 增加开服检测 3. 增加DIY服务器命令 4. 修复了亿些已知问题
#			5. 增加部分温和颜色提示
#小草哥哥 2023.01.23  > 1. 修复公测版关闭更新导致的永远在更新游戏
#小草哥哥 2023.02.10  > 1. 更新启动失败检测代码 2. 增加启动检测超时 3. 增加游戏更新网络检测 4. 重写模组管理 
#			5. 重写特殊名单管理 6. 重写存档管理 7. 增加释放存档压缩文件命令 8. 增加启动选项（./go.sh -h）
#			9. 优化模组自动更新 
#小草哥哥 2023.02.13  > 1. 修复单主世界结构检测Bug 2. 启动检测Bug修复 3. 增加启动选项（./go.sh -u 强制更新脚本）
#
# 已公测系统：Debian:11.05 Centos7:2009 UbuntuServer:22.04
#-------------------------------------------------------------------------------------------

# 通用变量

# 系统发行版本获取 例如：Arch linux
os=$(awk -F = '/^NAME/{print $2}' /etc/os-release | sed 's/"//g' | sed 's/ //g' | sed 's/Linux//g' | sed 's/linux//g' | sed s'#GNU/##g' | sed s'# ##g')

# Shell自动更新 
shellAuto="0"
# Shell脚本版本
shellVersion="5.53"

# 游戏版本
localVerGame="000000"
localVerGameBeta="000001"

# 内测码
betaKey="updatebeta"

# 游戏路径
gamePath=""

# 游戏目录
gameApp="$HOME/SteamGameApp"

# 正式版游戏路径
gamePathNormal="$gameApp/Dst"
# 公测版游戏路径
gamePathBeta="$gameApp/DstBeta"

# 当前存档路径
clusterPath="$gameApp/klei/DoNotStarveTogether"
# 当前版本
gameVersion=""

# 正式版存档路径
clusterPathNormal="$gameApp/klei/DoNotStarveTogether"
# 公测版存档路径
clusterPathBeta="$gameApp/klei/DoNotStarveTogetherBetaBranch"




# 0=正常执行 1=初次安装 4=退出指令
#isFlag

#常量
# 默认不更新脚本
NOT_UPDATE_SHELL="no"
NOT_UPDATE_GAME="no"

function ConfFile()
{	
	shellAuto="$(cat < "$HOME"/.dstconf/config | grep ShellAuto: | sed s'/ShellAuto://g')"
	# gitee 最新版本
	newShellVersion="$(cat <  "$HOME"/.dstconf/newshell | grep "iconfont icon-tag" | column -t | cut -d ' ' -f5 | sed s'#href="/changheqin/dst-server-for-linux-shell/tree/##g' | sed s'#"><i##g' | awk 'BEGIN {max = 0} {if ($1+0 > max+0) max=$1} END {print max}')"
	
	# 安装模式
	installMode="$(cat < "$HOME"/.dstconf/config | grep InstallMode: | sed s'/InstallMode://g')"

	# 本地版本
	localVerGame="$(cat < "$gamePathNormal"/version.txt)"
	
	if [[ "$installMode" == 0 || "$installMode" == 2 ]];then
	localVerGameBeta="$(cat < "$gamePathBeta"/version.txt)"
	fi
	
	# 当前版本
	gameVersion="$(cat < "$HOME"/.dstconf/config | grep GameVersion: | sed s'/GameVersion://g')"

	# 游戏路径
	gamePath="$(cat < "$HOME"/.dstconf/config | grep GamePath: | sed s'/GamePath://g')"
	
	# 存档路径
	clusterPath="$(cat < "$HOME"/.dstconf/config | grep ClusterPath: | sed s'/ClusterPath://g')"

	# 脚本更新控制参数更新
	sed -i "s#ShellAuto:.\$#ShellAuto:$shellAuto#g" "$HOME"/.dstconf/config
	# 脚本版本参数更新
	sed -i "s#ShellVersion:.*\$#ShellVersion:$shellVersion#g" "$HOME"/.dstconf/config
	# 本地正式版本号参数更新
	sed -i "s#LocalVersion:.*\$#LocalVersion:$localVerGame#g" "$HOME"/.dstconf/config
	# 本地公测版本号参数更新
	sed -i "s#LocalVersionBeta:.*\$#LocalVersionBeta:$localVerGameBeta#g" "$HOME"/.dstconf/config
	# 正式版存档路径参数更新
	sed -i "s#ClusterPathNormal:.*\$#ClusterPathNormal:$clusterPathNormal#g" "$HOME"/.dstconf/config
	# 公测版存档路径参数更新
	sed -i "s#ClusterPathBeta:.*\$#ClusterPathBeta:$clusterPathBeta#g" "$HOME"/.dstconf/config
	# 游戏目录参数更新
	sed -i "s#GameApp:.*\$#GameApp:$gameApp#g" "$HOME"/.dstconf/config
	# 正式版安装路径参数更新
	sed -i "s#GamePathNormal:.*\$#GamePathNormal:$gamePathNormal#g" "$HOME"/.dstconf/config
	# 公测版安装路径参数更新
	sed -i "s#GamePathBeta:.*\$#GamePathBeta:$gamePathBeta#g" "$HOME"/.dstconf/config
	# 当前存档路径参数更新
	sed -i "s#ClusterPath:.*\$#ClusterPath:$clusterPath#g" "$HOME"/.dstconf/config
	# 当前游戏路径参数更新
	sed -i "s#GamePath:.*\$#GamePath:$gamePath#g" "$HOME"/.dstconf/config

}

# 返回主菜单
function RollBackMain()
{

	if [[ "$1" == "clear" ]];then
		clear
	fi
	
	Main
}


# 配置文件生成
function CreatConfigFile()
{
	if [[ $isMode == 2 ]];then
		gameVersion="Beta"
		gamePath="$gamePathBeta"
		clusterPath="$clusterPathBeta"
	fi
echo "# Dst Config File
#
# 脚本自动更新
ShellAuto:$shellAuto
# 脚本版本
ShellVersion:$shellVersion
# 系统版本
OS:$os Linux
# 公测版本内测码
BetaKey:$betaKey
# 安装模式 0 正式版本和公测版本 1 单正式版本 2 单公测版本
InstallMode:$isMode
# 游戏版本 Normal:正式版本	Beta:公测版本
GameVersion:Normal
# 本地正式版本
LocalVersion:$localVerGame
# 本地公测版本
LocalVersionBeta:$localVerGameBeta
# 正式版存档路径
ClusterPathNormal:$clusterPathNormal
# 公测版存档路径
ClusterPathBeta:$clusterPathBeta
# 游戏目录
GameApp:$gameApp
# 正式版本安装路径
GamePathNormal:$gamePathNormal
# 公测版本安装路径
GamePathBeta:$gamePathBeta	
# 当前存档路径
ClusterPath:$clusterPathNormal
# 当前游戏安装路径
GamePath:$gamePathNormal" > "$HOME"/.dstconf/config
}

#****游戏程序进程函数

# 获取玩家信息 需传入 进程ID 程序版本 存档名称 世界结构
function GamePlayersList()
{
	# $1 世界进行ID
	# $2 游戏程序版本 Normal or Beta
	# $3 存档名称
	# $4 世界结构 Master or Caves
	# gamePlayerListFlag 0 == 没有玩家 gamePlayerListFlag 1 == 存在玩家
	gamePlayerListFlag=0
	# 唯一标签
	playerListDateLabel=$( date +%s%3N )
	# 日志内打印玩家列表
	screen -r "$1" -p 0 -X stuff "for i, v in ipairs(TheNet:GetClientTable()) do  print(string.format(\"PlayerList %s [%d] %s %s %s\",$playerListDateLabel, i-1, v.userid, v.name, v.prefab )) end$(printf \\r)"
	sleep 1s
	
	if [[ $2 == "Normal" && $(cat < "$clusterPathNormal"/"$3"/"$4"/server_log.txt | grep -a "$playerListDateLabel" | cut -d ' ' -f 4-15 | tail -n +2 | grep -v "\[Host\]" | wc -l) -gt 0  ]];then
		echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
		echo "存档名称: $3"
		echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
		cat < "$clusterPathNormal"/"$3"/"$4"/server_log.txt | grep -a "$playerListDateLabel" | cut -d ' ' -f 4-15 | tail -n +2 | grep -v "\[Host\]"
		echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
		
		gamePlayerListFlag=1
		
	elif [[ $2 == "Beta" && $(cat < "$clusterPathBeta"/"$3"/"$4"/server_log.txt | grep -a "$playerListDateLabel" | cut -d ' ' -f 4-15 | tail -n +2 | grep -v "\[Host\]" | wc -l) -gt 0  ]];then
		echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
		echo "存档名称: $3"
		echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
		cat < "$clusterPathBeta"/"$3"/"$4"/server_log.txt | grep -a "$playerListDateLabel" | cut -d ' ' -f 4-15 | tail -n +2 | grep -v "\[Host\]"
		echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"	
		
		gamePlayerListFlag=1
	else
	
		gamePlayerListFlag=0
	
	fi
	
}

# 发送公告 
function GameAnnounce()
{
	# $1 进程ID 
	# $2 公告内容
	screen -r "$1" -p 0 -X stuff "c_announce(\"$2\")$(printf \\r)"
}

# 存档
function GameSave()
{
	# $1 进程ID 
	screen -r "$1" -p 0 -X stuff "c_save()$(printf \\r)"
}

# 回档
function GameRollBack()
{
	# $1 进程ID 
	# $2 回档天数
	screen -r "$1" -p 0 -X stuff "c_rollback('$2')$(printf \\r)"
}




#****服务器函数

# 进程ID
function MasterProcess()
{
	# $1 游戏程序版本 Normal or Beta
	# $2 存档名称
	# $3 存档结构
	masterProcess=$( screen -ls | grep "$1" | grep "$2" | grep "$3" | awk '{print $1}' | cut -d . -f1 )
}

# 快速存档
function QuickSave()
{
	local cid
	local clusterNameIndex
	
	cid=$( screen -ls | grep -P 'Master|Caves' | sed s'/\./ /g' | awk '{print $6}' | sort -u | wc -l )
	
	for i in $(seq "$cid")
	do
		# 运行存档名称 合集
		clusterNameIndex=$( screen -ls | grep -P 'Master|Caves' | sed s'/\./ /g' | awk '{print $6}' | sort -u | awk NR=="$i"'{print $0}' )
		
		# 程序版本检测
		if [[ $(screen -ls | grep -P 'Master|Caves' | grep -c 'Normal') -gt 0 ]];then
			# 结构检测
			if [[ -d $clusterPathNormal/$clusterNameIndex/Master || -d $clusterPathNormal/$clusterNameIndex/Master && -d  $clusterPathNormal/$clusterNameIndex/Caves ]];then
				# 主进程获取
				MasterProcess Normal "$clusterNameIndex" Master
			elif [[ -d  $clusterPathNormal/$clusterNameIndex/Caves ]];then
				# 主进程获取
				MasterProcess Normal "$clusterNameIndex" Caves
			fi
			# 存档
			GameSave "$masterProcess"
		elif [[ $(screen -ls | grep -P 'Master|Caves' | grep -c 'Beta') -gt 0 ]];then
			# 结构检测
			if [[ -d $clusterPathBeta/$clusterNameIndex/Master || -d $clusterPathNormal/$clusterNameIndex/Master && -d  $clusterPathNormal/$clusterNameIndex/Caves ]];then
				# 主进程获取
				MasterProcess Beta "$clusterNameIndex" Master
			elif [[ -d  $clusterPathBeta/$clusterNameIndex/Caves ]];then
				# 主进程获取
				MasterProcess Beta "$clusterNameIndex" Caves
			fi
			# 存档
			GameSave "$masterProcess"
		fi

	done
	
	RollBackMain clear
}

# 快速回档
function QuickRollBack()
{
	local cName # 存档名称
	local cNameId
	local cDay 

	cName=$(screen -ls | grep -P 'Master|Caves' | sed s'/\./ /g' | awk '{print $6}' | sort -u | awk '{print NR,$1}')
	# 供用户选择存档名
	echo "-------------------------------------"
	echo "$cName"
	echo "-------------------------------------"
	echo "请选择要回溯的存档，输入序号即可(quit返回主菜单)："
	read -r cNameId
	if [[ $cNameId == quit ]];then 
		RollBackMain clear
	fi
	# 存档名称
	cName=$(echo "$cName" | awk NR=="$cNameId"'{print $2}')

	while :
	do
	echo "请输入要回溯的天数，输入天数即可(默认1天，默认回车即可,quit返回主菜单)："
	read -r cDay
	if [[ $cDay == quit ]];then
		RollBackMain clear
	elif [[ $cDay -le 999 && $cDay -gt 0 ]];then 
		cDay
		break
	elif [[ -z "$cDay" || "$cDay" == "" ]];then
		cDay=1
		break
	else
		echo "输入不是数字，请重新输入天数！"
	fi
	done

	# 版本检测
	if [[ $(screen -ls | grep -P 'Master|Caves' | grep -c 'Normal') -gt 0 ]];then
		# 结构检测
		if [[ -d $clusterPathNormal/$cName/Master || -d $clusterPathNormal/$clusterNameIndex/Master && -d  $clusterPathNormal/$cName/Caves ]];then
			# 主进程获取
			MasterProcess Normal "$cName" Master
		elif [[ -d  $clusterPathNormal/$cName/Caves ]];then
			# 主进程获取
			MasterProcess Normal "$cName" Caves
		fi
		GameRollBack "$masterProcess" "$cDay"
	elif [[ $(screen -ls | grep -P 'Master|Caves' | grep -c 'Beta') -gt 0 ]];then
		# 结构检测
		if [[ -d $clusterPathBeta/$cName/Master || -d $clusterPathNormal/$clusterNameIndex/Master && -d  $clusterPathBeta/$cName/Caves ]];then
			# 主进程获取
			MasterProcess Beta "$cName" Master
		elif [[ -d  $clusterPathBeta/$cName/Caves ]];then
			# 主进程获取
			MasterProcess Beta "$cName" Caves
		fi
		GameRollBack "$masterProcess" "$cDay"

	fi

	RollBackMain clear

}

# 快速公告
function QuickAnnounce()
{
	local cName # 存档名称
	local cNameId
	local str

	cName=$(screen -ls | grep -P 'Master|Caves' | sed s'/\./ /g' | awk '{print $6}' | sort -u | awk '{print NR,$1}')

	# 供用户选择存档名
	echo "-------------------------------------"
	echo "$cName"
	echo "-------------------------------------"
	echo "请选择要发布公告的存档，输入序号即可(返回请输入quit)："
	read -r cNameId
	# 存档名称
	cName=$(echo "$cName" | awk NR=="$cNameId"'{print $2}')
	if [[ $cNameId == quit ]];then
		RollBackMain clear
	fi
	echo "请输入要发布公告的内容(返回请输入quit)："
	echo "-----------------------"
	read -r str
	if [[ $str == quit ]];then
		RollBackMain clear
	fi	

	# 版本检测
	if [[ $(screen -ls | grep -P 'Master|Caves' | grep -c 'Normal') -gt 0 ]];then

		# 结构检测
		if [[ -d $clusterPathNormal/$cName/Master || -d $clusterPathNormal/$cName/Master && -d  $clusterPathNormal/$cName/Caves ]];then
			# 主进程获取
			MasterProcess Normal "$cName" Master
		elif [[ -d  $clusterPathNormal/$cName/Caves ]];then
			# 主进程获取
			MasterProcess Normal "$cName" Caves
		fi
		GameAnnounce "$masterProcess" "$str"
	elif [[ $(screen -ls | grep -P 'Master|Caves' | grep -c 'Beta') -gt 0 ]];then
		# 结构检测
		if [[ -d $clusterPathBeta/$cName/Master || -d $clusterPathNormal/$cName/Master && -d  $clusterPathBeta/$cName/Caves ]];then
			# 主进程获取
			MasterProcess Beta "$cName" Master
		elif [[ -d  $clusterPathBeta/$cName/Caves ]];then
			# 主进程获取
			MasterProcess Beta "$cName" Caves
		fi
		GameAnnounce "$masterProcess" "$str"

	fi

	RollBackMain clear

}

function OnlinePlayers()
{
	local cid
	local cName
	local yes

	# 正式版本进程
	if [[ $(screen -ls | grep -P 'Master|Caves' | grep -c 'Normal') -gt 0 ]];then
		# 正式版本存档长度
		cid=$(screen -ls | grep -P 'Master|Caves' | sed s'/\./ /g' | grep 'Normal' | awk '{print $6}' | sort -u | wc -l)

		for i in $(seq "$cid" ) 
		do
			# 获取存档名称
			cName=$(screen -ls | grep -P 'Master|Caves' | sed s'/\./ /g' | grep 'Normal' | awk '{print $6}' | sort -u | awk NR=="$i"'{print $0}')
			# 存档结构检测
			if [[ -d "$clusterPathNormal"/"$cName"/Master || -d "$clusterPathNormal"/"$cName"/Master && -d "$clusterPathNormal"/"$cName"/Caves ]];then
				
				# 进程获取
				MasterProcess Normal "$cName" Master
				
				# 玩家人数显示
				GamePlayersList "$masterProcess" Normal "$cName" Master
				echo ""
				if [[ $gamePlayerListFlag -eq 0 ]];then
					echo "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"
					echo "存档名称: $cName"
					echo "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"
					echo " 该存档没有任何玩家！"
					echo "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"	
				fi

			elif [[ -d "$clusterPathNormal"/"$cName"/Caves ]];then
			
				# 进程获取
				MasterProcess Normal "$cName" Caves
				# 玩家人数显示
				GamePlayersList "$masterProcess" Normal "$cName" Caves
				
			fi
		done
	fi

	# 公测版本进程
	if [[ $(screen -ls | grep -P 'Master|Caves' | grep -c 'Beta') -gt 0 ]];then
		# 公测版本存档长度
		cid=$(screen -ls | grep -P 'Master|Caves' | sed s'/\./ /g' | grep 'Beta' | awk '{print $6}' | sort -u | wc -l)
		
		for i in $(seq "$cid" ) 
		do
			# 获取存档名称
			cName=$(screen -ls | grep -P 'Master|Caves' | sed s'/\./ /g' | grep 'Beta' | awk '{print $6}' | sort -u | awk NR=="$i"'{print $0}')
			
			# 存档结构检测
			if [[ -d "$clusterPathBeta"/"$cName"/Master || -d "$clusterPathBeta"/"$cName"/Master && -d "$clusterPathBeta"/"$cName"/Caves ]];then
				
				# 进程获取
				MasterProcess Beta "$cName" Master
				
				# 玩家人数显示
				GamePlayersList "$masterProcess" Beta "$cName" Master
				echo ""
				if [[ $gamePlayerListFlag -eq 0 ]];then
					echo "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"
					echo "存档名称: $cName"
					echo "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"
					echo "该存档没有任何玩家！"
					echo "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"	
				fi

			elif [[ -d "$clusterPathBeta"/"$cName"/Caves ]];then
			
				# 进程获取
				MasterProcess Beta "$cName" Caves
				# 玩家人数显示
				GamePlayersList "$masterProcess" Beta "$cName" Caves
				
			fi
		done
	fi

	echo ""
	echo "是否返回主菜单：[y]"
	read -r yes
	if [[ $yes == y ]];then
		RollBackMain clear
	else
		clear
		OnlinePlayers
	fi

}

function DiyGameCommand()
{
	local id
	
	local pid
	local world
	local bit
	local ver
	local cName
	local ispid
	local yes
	local gamecommand
	local isLog
	local yes
	local yes0

	echo
	# 选择操作进程
	id=$(screen -ls | grep -c -P 'Master|Caves' )
	for i in $(seq "$id")
	do
		if [[ $i == 1 ]];then
		printf "  %-13s %-18s  %-3s   %-8s %-15s\n" "进程号" "存档名称" "架构" "世界类型" "世界名称"
		echo "  ---------------------------------------------------"
		fi
		pid=$(screen -ls | grep -P 'Master|Caves' | cut -d '.' -f1 | awk '{print $1}' | awk NR=="$i"'{print $0}')
		wName=$(screen -ls | grep -P 'Master|Caves' | cut -d '.' -f3 | awk NR=="$i"'{print $0}')
		bit=$(screen -ls | grep -P 'Master|Caves' | cut -d '.' -f4 | awk NR=="$i"'{print $0}')
		world=$(screen -ls | grep -P 'Master|Caves' | cut -d '.' -f2 | awk NR=="$i"'{print $0}')
		cName=$(screen -ls | grep -P 'Master|Caves' | cut -d '.' -f6 | awk NR=="$i"'{print $0}')
		printf "  %-10s %-15s  %-3s   %-8s %-15s\n" "$pid" "$cName" "$bit" "$world" "$wName"

	done

	echo 
	echo "请输入进程号(quit退出):" 
	read -r ispid
	ver=$(screen -ls | grep "$ispid" | cut -d '.' -f5)
	world=$(screen -ls | grep "$ispid" | cut -d '.' -f2)
	cName=$(screen -ls | grep "$ispid" | cut -d '.' -f6)
	if [[ $ispid == quit ]];then
		RollBackMain clear
	fi
	while :
	do
		# 输入游戏代码
		echo "请输入控制台代码(quit退出)："
		read -r gamecommand
		if [[ $gamecommand == quit ]];then
			RollBackMain clear
		fi
		screen -r "$ispid" -p 0 -X stuff "$gamecommand $(printf \\r)"

		sleep 2s
		echo "---------------------------------------------------------------"
		# 返回最新的日志
		if [[ $ver == Normal ]];then
			tail -n 15 "$clusterPathNormal"/"$cName"/"$world"/server_log.txt
		elif [[ $ver == Beta ]];then
			tail -n 15 "$clusterPathBeta"/"$cName"/"$world"/server_log.txt
		fi
		# 是否继续
		echo "是否继续控制服务器 [u]更新日志 [y]继续控制服务器 [n]返回主菜单"
		read -r yes
		if [[ $yes == n ]];then
			break
		elif [[ $yes == u ]];then
				isLog=false
				yes0=""
				while :
				do
				if [[ $isLog == true ]];then
				echo "是否继续更新日志？ [u]更新日志 [y]继续控制服务器 [n]返回主菜单"
				read -r yes0
				fi
	
				if [[ $yes0 == y ]];then
					break
				elif [[ $yes0 == n ]];then
					RollBackMain clear
				fi

				echo "---------------------------------------------------------------"
				if [[ $ver == Normal ]];then
					tail -n 15 "$clusterPathNormal"/"$cName"/"$world"/server_log.txt
					elif [[ $ver == Beta ]];then
						tail -n 15 "$clusterPathBeta"/"$cName"/"$world"/server_log.txt
				fi
				isLog=true
				done
				
		else
			continue
		fi
	done
	RollBackMain clear
	
}

# 颜色函数
function EchoColor() {
    # $1 文字颜色 $2 背景颜色
    # $1 : 0=默认设置 1=高亮显示 4=下划线 5=闪烁 7=反白显示 8=不可见
	# $1 $2 : 30=前景黑 40=背景黑 
	#		  31,41=红色 32,42=绿色 33,43=黄色 34,44=蓝色
	#		  35,35=紫红色 36,46=青蓝色 37,47=白色
	if [[ -z $1 || $1 == "" || -z $2 || $2 == "" ]];then
    	fontColor="37"
    	bgColor="40"
	else
		fontColor=$1
		bgColor=$2
	fi
    #格式 echo -e "\033[字背景颜色;字体颜色m字符串\033[控制码"
    #echo -e "\e[${fontColor};${bgColor}m $1 \e[0m"

	# $COLOR && echo 7788 && $RESET
	COLOR="echo -en \\E[${fontColor};${bgColor}m"
	RESET="echo -en \\E[0;39m"
	
}

# 启动服务器
function StartServer()
{	
	local cNameArray
	local cNameId
	local newfile2
	
	# 正式版本
	if [[ "$1" == Normal ]];then

		if [[ "$installMode" == 2 ]];then
			echo "该服务器未安装正式版本，如有需求退出本脚本请执行以下命令！"
			echo "rm ${HOME}/.steamcmd -rf "
			echo "执行完成后，再次执行脚本选择完整安装即可！"
			RollBackMain
		fi 

		# 如果配置文件路径为公测版本则替换为正式版本
		sed -i "s#GamePath:.*\$#GamePath:$gamePathNormal#g" "$HOME"/.dstconf/config
		sed -i "s#ClusterPath:.*\$#ClusterPath:$clusterPathNormal#g" "$HOME"/.dstconf/config
		sed -i "s#GameVersion:.*\$#GameVersion:Normal#g" "$HOME"/.dstconf/config
		# 重载配置文件
		ConfFile
	fi

	#公测版本
	if [[ "$1" == Beta ]];then
		# 公测通道检测
		if [[ "$remoteBeta1" != 1 ]];then
			clear
			EchoColor "0" "35"
			echo ""
			$COLOR && echo "公测通道已被官方关闭,服务器无法启动！" && $RESET
			$COLOR && echo "公测通道已被官方关闭,服务器无法启动！" && $RESET
			$COLOR && echo "公测通道已被官方关闭,服务器无法启动！" && $RESET
			echo ""
			RollBackMain
		fi
		if [[ "$installMode" == 1 ]];then
			echo "该服务器未安装公测版本，如有需求退出本脚本请执行以下命令！"
			echo "rm ${HOME}/.steamcmd -rf "
			echo "执行完成后，再次执行脚本选择完整安装即可！"
			RollBackMain
		fi 

		# 如果配置文件路径为正式版本则替换为公测版本
		sed -i "s#GamePath:.*\$#GamePath:$gamePathBeta#g"  "$HOME"/.dstconf/config
		sed -i "s#ClusterPath:.*\$#ClusterPath:$clusterPathBeta#g"  "$HOME"/.dstconf/config
		sed -i "s#GameVersion:.*\$#GameVersion:Beta#g" "$HOME"/.dstconf/config
		# 重载配置文件
		ConfFile
		
	fi
	# 内存大于3.5G 默认64bit 或  Arch 系统必须是 64bit
	if [[ "$(cat < /proc/meminfo | grep MemTotal | sed s'/MemTotal://g' | sed s'/kB//g' | sed s'/ //g')" -gt 3584000 || "$os" == "Arch" ]];then
		modeBitPath=64
		modeBit=_x64
	# 内存小于3.5G 默认32bit
	else
		modeBitPath=""
		modeBit=""
	fi
	
	cNameArray=$(ls -l "$clusterPath" | awk '/^d/ {print $NF}' | awk '{print NR,$NF}')
	
	echo "============================================"
	echo "存档目录(新建请输入新的存档名称)"
	echo -e "\033[33m$cNameArray \033[0m"
	echo "============================================"
	echo "请输入存档序号(返回输入quit)"
	read -r cNameId
	
	if [[ $( ls -l "$clusterPath" | awk '/^d/ {print $NF}' | wc -l ) -ge $cNameId && $cNameId -ne 0 ]];then
	
		clusterCode=$(echo "$cNameArray" | awk NR=="$cNameId"'{print $2}')

		if [[ -d "$clusterPath/$clusterCode" ]];then
			FileChose
		fi
	elif [[ -z $cNameId || $cNameId == "" || $cNameId == quit ]];then
			RollBackMain clear
	else
		clusterCode=$cNameId
		echo "存档不存在，是否新建？[y/n]" 
		read -r newfile2
		while :
		do
			case $newfile2 in
				y)ModeChose
				break;;
				n)RollBackMain clear
				break;;
			esac
		done
	fi

	
}


# 检测服务器是否正常运行
function StartCheck() 
{
	# $1=存档路径 $2=存档代码 $3=存档结构
	
	for i in $(seq 180);
	do
		if [[ -f "${1}/${2}/${3}/server_log.txt" ]];then
		
			sleep 1s
			
			LogCheck "${1}/${2}/${3}/server_log.txt" "Sim paused" "shard LUA is now ready!"
			if [[ logCheckNum2 -gt 0 || logCheckNum3 -gt 0 ]];then
				EchoColor "0" "32"
				if [[ $3 == "Master" ]];then
					
					$COLOR && echo "地上服务器启动成功！" && $RESET
				else
					$COLOR && echo "洞穴服务器启动成功！" && $RESET
				fi
				break
			fi
			LogCheck "${1}/${2}/${3}/server_log.txt" "Your Server Will Not Start !!!"
			if [[ logCheckNum2 -gt 0 ]];then
				EchoColor "0" "31"
				if [[ $3 == "Master" ]];then
					$COLOR && echo "地上服务器未启动，请检查令牌是否有效！" && $RESET
				else
					$COLOR && echo "洞穴服务器未启动，请检查令牌是否有效！" && $RESET
				fi
				break
			fi
			LogCheck "${1}/${2}/${3}/server_log.txt" "Failed to send shard broadcast message"
			if [[ logCheckNum2 -gt 0 ]];then
				EchoColor "0" "31"
				if [[ $3 == "Master" ]];then
					$COLOR && echo "地上服务器未启动，请检查网络或尝试重新启动！" && $RESET
				else
					$COLOR && echo "洞穴服务器未启动，请检查网络或尝试重新启动！" && $RESET
				fi
				break
			fi
			LogCheck "${1}/${2}/${3}/server_log.txt" "Unhandled exception during server startup: RakNet UDP startup failed"
			if [[ logCheckNum2 -gt 0 ]];then
				EchoColor "0" "31"
				if [[ $3 == "Master" ]];then
					$COLOR && echo "地上服务器未启动，请检查 ${2}/${3}/server.ini 端口是否被占用！" && $RESET
				else
					$COLOR && echo "洞穴服务器未启动，请检查 ${2}/${3}/server.ini 端口是否被占用！" && $RESET
				fi
				break
			fi
			LogCheck "${1}/${2}/${3}/server_log.txt" "Error deserializing lua state for entity shard_network[100034]"
			if [[ logCheckNum2 -gt 0 ]];then
				EchoColor "0" "31"
				if [[ $3 == "Master" ]];then
					$COLOR && echo "地上服务器未启动，${2}/cluster.ini 端口被占用！" && $RESET
				else
					$COLOR && echo "洞穴服务器未启动，${2}/cluster.ini 端口被占用！" && $RESET
				fi
				break
			fi
			LogCheck "${1}/${2}/${3}/server_log.txt" "Unable to connect to shard master server: INVALID_PARAMETER"
			if [[ logCheckNum2 -gt 0 ]];then
				EchoColor "0" "31"
				if [[ $3 == "Master" ]];then
					$COLOR && echo "地上服务器未启动，${2}/cluster.ini 主服务器地址错误！" && $RESET
				else
					$COLOR && echo "洞穴服务器未启动，${2}/cluster.ini 主服务器地址错误！" && $RESET
				fi
				break
			fi
			LogCheck "${1}/${2}/${3}/server_log.txt" "Server registered via geo DNS in"
			if [[ logCheckNum2 -gt 0 ]];then
				EchoColor "0" "31"
				if [[ $3 == "Master" ]];then
					$COLOR && echo "地上服务器已启动，但存档注册Klei 列表服务器出现故障！请先关闭存档，检查 ${2}/cluster.ini 再启动！" && $RESET
				else
					$COLOR && echo "洞穴服务器已启动，但存档注册Klei 列表服务器出现故障！请先关闭存档，检查 ${2}/cluster.ini 再启动！" && $RESET
				fi
				break
			fi
			if [[ "$i" -eq 180 ]];then
				EchoColor "0" "31"
				if [[ $3 == "Master"  ]];then
					$COLOR && echo "地上服务器启动超时，请检查模组或配置文件！" && $RESET
				else
					$COLOR && echo "洞穴服务器启动超时，请检查模组或配置文件！" && $RESET
				fi
				
				break
			fi
			
		else
			EchoColor "0" "31"
			$COLOR && echo "未检测到启动日志，启动失败！" && $RESET
			break
		fi
	done
}


# 控制面板
function ControlPanel()
{
	local input
	
	echo "-------------------------------------------------"
	echo " 按回车返回主菜单！"
	echo "-------------------------------------------------"
	echo "| [1]管理特殊名单	[2]管理模组		|"
	echo "-------------------------------------------------"
	echo "| [3]管理存档		[4]手动更新脚本		|"
	echo "-------------------------------------------------"
	echo "| [5]手动更新正式版本	[6]手动更新公测版本	|"
	echo "-------------------------------------------------"
	read -r input
	
	if [[ "$input" -le 6 && "$input" -gt 0  ]];then
		case $input in
			 1)ListManage;;
			 2)ModManage;;
			 3)FileManage;;
			 4)UpdateShell Manual;;
			 5)InstallGame Normal;;
			 6)InstallGame Beta;;
		esac
	elif [[ -z "$input" ]];then 
		RollBackMain clear
	else 
		echo "输入有误,请重新输入！"
		ControlPanel
	fi
}

# 白名单管理
function SetWhite()
{
	EchoColor "0" "31"
	local white1
	local ID2
	
	echo "============================================"
	echo "[1]加入白名单 [2]放出白名单 "
	read -r white1
	case $white1 in
		1)
		echo "============================================"
		echo "请输入要加入白名单的Klei ID"
		read -r ID2
		if [[ -d $clusterPath/$clusterCode/ ]];then
			if [[ ! -f "$clusterPath"/"$clusterCode"/whitelist.txt ]];then touch "$clusterPath"/"$clusterCode"/whitelist.txt; fi
			
			if [[  $(grep -c "$ID2" "$clusterPath"/"$clusterCode"/whitelist.txt) -eq 0 ]];then 
				echo "$ID2" >> "$clusterPath"/"$clusterCode"/whitelist.txt
				$COLOR && echo "已为这个基佬预留一个位置" && $RESET
			else
				$COLOR && echo "这个基佬已经有一个位置" && $RESET
			fi
		fi
		;;
		2)
		echo "============================================"
		echo "请输入要解除白名单的Klei ID"
		read -r ID2
		if [[ -d $clusterPath/$clusterCode/ ]];then
			if [[ $(grep "$ID2" "$clusterPath"/"$clusterCode"/whitelist.txt) -eq 0 ]];then 
				sed -i "/$ID2/d" "$clusterPath"/"$clusterCode"/whitelist.txt
				$COLOR && echo "预留位置已开放" && $RESET
			else
				$COLOR && echo "没有这个基佬的预留位置" && $RESET
			fi
		fi
		;;
	esac
	RollBackMain
}

# 黑名单管理
function SetBlack()
{
	EchoColor "0" "31"
	local black1
	local ID2
	
	echo "============================================"
	echo "[1]加入黑名单 [2]放出黑名单 "
	read -r black1
	case $black1 in
		1)
		echo "============================================"
		echo "请输入要加入黑名单的Klei ID"
		read -r ID2
		if [[ -d $clusterPath/$clusterCode/ ]];then
			if [[ ! -f "$clusterPath"/"$clusterCode"/blacklist.txt ]];then touch "$clusterPath"/"$clusterCode"/blacklist.txt; fi
			
			if [[ $(grep "$ID2" "$clusterPath"/"$clusterCode"/blacklist.txt) -eq 0 ]];then 
				echo "$ID2" >> "$clusterPath"/"$clusterCode"/blacklist.txt
				$COLOR && echo "SB已被关入地上小黑屋" && $RESET
			else
				$COLOR && echo "这个SB已经在小黑屋" && $RESET
			fi
		fi
		;;
		2)
		echo "============================================"
		echo "请输入要解除黑名单的Klei ID"
		read -r ID2
		if [[ -d $clusterPath/$clusterCode/ ]];then
			if [[ $(grep -c "$ID2" "$clusterPath"/"$clusterCode"/blacklist.txt) -gt 0 ]];then 
				sed -i "/$ID2/d" "$clusterPath"/"$clusterCode"/blacklist.txt
				
				$COLOR && echo "已放出地上小黑屋" && $RESET
			else
				$COLOR && echo "这个基佬不在小黑屋" && $RESET
				
			fi
		fi
		;;
	esac
	
	ControlPanel
}

# 添加管理员
function SetAdmin()
{	
	EchoColor "0" "31"
	local admin1
	local ID2
	echo "============================================"
	echo "[1]提升管理员 [2]解除管理员 "
	read -r admin1
	case $admin1 in
		1)
		echo "============================================"
		echo "请输入要提升管理员的Klei ID"
		read -r ID2
		if [[ -d $clusterPath/$clusterCode/ ]];then
			if [[ ! -f "$clusterPath"/"$clusterCode"/adminlist.txt ]];then touch "$clusterPath"/"$clusterCode"/adminlist.txt; fi
			
			if [[ $(grep -c "$ID2" "$clusterPath"/"$clusterCode"/adminlist.txt) -eq 0 ]];then 
				echo "$ID2" >> "$clusterPath"/"$clusterCode"/adminlist.txt
				$COLOR && echo "存档管理员已添加" && $RESET
			else
				$COLOR && echo "这个基佬已经是管理员" && $RESET
			fi
		fi
		;;
		
		2)
		echo "============================================"
		echo "请输入要解除管理员的Klei ID"
		read -r ID2
		if [[ -d $clusterPath/$clusterCode/ ]];then
			if [[ $(grep -c "$ID2" "$clusterPath"/"$clusterCode"/adminlist.txt) -gt 0 ]];then 
				sed -i "/$ID2/d" "$clusterPath"/"$clusterCode"/adminlist.txt
				$COLOR && echo "存档管理员已移除" && $RESET
			else
				$COLOR && echo "这个基佬不是管理员" && $RESET
			fi
		fi
		;;
		
	esac
	
	ControlPanel
}

# 存档管理员设置
function ListManage()
{
	local list1
	local isVer
	local cNameArray
	local cNameId
	echo "请输入要管理的版本 [1] 正式版本 [2] 公测版本"
	read -r isVer
	case $isVer in
		1) clusterPath=$clusterPathNormal ;;
		2) clusterPath=$clusterPathBeta ;;
		*) clear ; echo "输入错误，请重新输入！" ;  ListManage ;;
	esac
	
	echo "============================================"
	echo "存档目录"
	cNameArray=$(ls -l "$clusterPath" | awk '/^d/ {print $NF}' | awk '{print NR,$NF}')
	echo -e "\033[33m$cNameArray \033[0m"
	echo "请输入要管理的存档序号"
	read -r cNameId
	if [[ $( ls -l "$clusterPath" | awk '/^d/ {print $NF}' | wc -l ) -ge $cNameId && $cNameId -ne 0 ]];then
		clusterCode=$(echo "$cNameArray" | awk NR=="$cNameId"'{print $2}')
	else
		ListManage
	fi
	while :
	do
		echo "============================================"
		echo "[1]设置管理员 [2]管理黑名单 [3]管理白名单 [0]返回主菜单"
		read -r list1
		case $list1 in
			0)Main
			break;;
			1)SetAdmin
			break;;
			2)SetBlack
			break;;
			3)SetWhite
			break;;
		esac
	done
}

# 模组更新检测
function CheckUpdateMod()
{
	local NeedsUpdate
	local NeedsDownload
    if [[ -f "$gameApp"/V2Mods/appworkshop_322330.acf ]];then
		num=0
		while :
		do
			(( num++ )) || true
			sleep 1s
			NeedsUpdate=$(awk '/NeedsUpdate/{print $2}' "$gameApp"/V2Mods/appworkshop_322330.acf | sed 's/"//g')
			NeedsDownload=$(awk '/NeedsDownload/{print $2}' "$gameApp"/V2Mods/appworkshop_322330.acf | sed 's/"//g')
			if [[ $num -eq 120 || $NeedsUpdate -eq 0 && $NeedsDownload -eq 0 || $logCheckNum3 -ge 1 || $logCheckNum2 -ge 1 ]];then
				break
			fi
			if [[ "$NeedsUpdate" -ne 0 ]];then
				# 模组需更新
				UpdateMod
				continue
			fi
			if [[ "$NeedsDownload" -ne 0 ]];then
				# 模组需下载
				UpdateMod
				continue
			fi
		done
    fi
}

# MOD自动更新管理
function UpdateMod()
{
    cd "$gamePath"/bin || exit
    
    ./dontstarve_dedicated_server_nullrenderer -only_update_server_mods -ugc_directory "$gameApp"/V2Mods -persistent_storage_root "$gameApp"/klei -cluster "autoupdatemod"  > "$HOME"/.dstconf/update_mod.log  2>&1 &
	
	EchoColor "0" "31"
	$COLOR && echo "更新模组进程操作成功，请耐心等待！" && $RESET
	if [[ -f "${clusterPath}/autoupdatemod/Master/server_log.txt" ]];then
		for i in $(seq 90); do
			LogCheck ""$clusterPath"/autoupdatemod/Master/server_log.txt" "FinishDownloadingServerMods Complete!" "[Workshop] ItemQuery finished downloading everything"
			if [[ logCheckNum2 -gt 0 || logCheckNum3 -gt 0 ]];then
				EchoColor "0" "32"
					$COLOR && echo "模组更新成功" && $RESET
				break
			fi
			sleep 2s
		done
	else
		EchoColor "0" "31"
		$COLOR && echo "未检测到模组更新日志！" && $RESET
	fi
	cd "$HOME" || exit
}

# 更新MOD自动添加
function AddAutoUpdateMod()
{
	local modTotal
	local modID
	# 重载配置
	ConfFile
	# 判断文件是否存在
	if [[ -f "$clusterPath"/"$clusterCode"/Master/modoverrides.lua ]];then
		# 循环次数
		modTotal=$(cat < "$clusterPath"/"$clusterCode"/Master/modoverrides.lua | grep -c 'workshop-')

	elif [[ -f "$clusterPath"/"$clusterCode"/Caves/modoverrides.lua ]];then
		# 循环次数
		modTotal=$(cat < "$clusterPath"/"$clusterCode"/Caves/modoverrides.lua | grep -c 'workshop-')
	else
		modTotal=0
		echo "没有发现模组文件！"
	fi

	# 循环添加模组到更新文件
	for item in $(seq "$modTotal" ); do
		
		# 判断文件是否存在
		if [[ -f "$clusterPath"/"$clusterCode"/Master/modoverrides.lua ]];then
			# 模组ID
			modID=$(cat < "$clusterPath"/"$clusterCode"/Master/modoverrides.lua | grep 'workshop-' | cut -d '"' -f2 | sed s'#workshop-##g' | awk NR=="$item"'{print $0}')

		elif [[ -f "$clusterPath"/"$clusterCode"/Caves/modoverrides.lua ]];then
			# 模组ID
			modID=$(cat < "$clusterPath"/"$clusterCode"/Caves/modoverrides.lua | grep 'workshop-' | cut -d '"' -f2 | sed s'#workshop-##g' | awk NR=="$item"'{print $0}')

		fi

		# 添加ID 操作
		if [[ $(cat < "$gamePathNormal"/mods/dedicated_server_mods_setup.lua | grep -c "$modID") -eq 0 || $(cat < "$gamePathBeta"/mods/dedicated_server_mods_setup.lua | grep -c "$modID") -eq 0 ]];then

			if [[ $(cat < "$gamePathNormal"/mods/dedicated_server_mods_setup.lua | grep -c "$modID") -eq 0 ]];then
			
				echo "        ServerModSetup(\"$modID\")" >> "$gamePathNormal"/mods/dedicated_server_mods_setup.lua
			fi
			
			if [[ $(cat < "$gamePathBeta"/mods/dedicated_server_mods_setup.lua | grep -c "$modID") -eq 0 ]];then
				echo "        ServerModSetup(\"$modID\")" >> "$gamePathBeta"/mods/dedicated_server_mods_setup.lua
			fi
			echo ""
			echo "$modID 模组添加完成！"

		else
			echo ""
			echo "这个 $modID 模组之前已被添加！"

		fi
	done
	
	sleep 3s

}

# 删除Mod
function RemMod()
{
	EchoColor "0" "31"
	local modID
	local mNameId
	local mNameArray
	
	while :
	do
		if [[ -d $clusterPath/$clusterCode/Master ]];then 
			mNameArray=$(cat < "$clusterPath"/"$clusterCode"/Master/modoverrides.lua | grep "[0-9]\{5,\}" | cut -d "-" -f2 | cut -d '"' -f1 | awk '{print NR,$NF}')
		elif [[ -d $clusterPath/$clusterCode/Caves ]];then
			mNameArray=$(cat < "$clusterPath"/"$clusterCode"/Caves/modoverrides.lua | grep "[0-9]\{5,\}" | cut -d "-" -f2 | cut -d '"' -f1 | awk '{print NR,$NF}')
		fi
		echo "------------"
		echo -e "\033[33m$mNameArray \033[0m"
		echo "请输入要清理的模组序号 | 输入【0】返回主菜单"
		read -r mNameId
		if [[ $( cat < "$clusterPath"/"$clusterCode"/Master/modoverrides.lua | grep "[0-9]\{5,\}" | cut -d "-" -f2 | wc -l ) -ge $mNameId && $mNameId -ne 0 ]];then
			modID=$(echo "$mNameArray" | awk NR=="$mNameId"'{print $2}')
		elif [[ $( cat < "$clusterPath"/"$clusterCode"/Caves/modoverrides.lua | grep "[0-9]\{5,\}" | cut -d "-" -f2 | wc -l ) -ge $mNameId && $mNameId -ne 0 ]];then
			modID=$(echo "$mNameArray" | awk NR=="$mNameId"'{print $2}')
		elif [[ $mNameId -eq 0 ]];then
			modID=0
		fi
		
		case $modID in
		
			0)break;;
			
			*)
			if [[ -d $clusterPath/$clusterCode/Master ]];then
				if [[ $(grep -c "$modID" "$clusterPath"/"$clusterCode"/Master/modoverrides.lua) -gt 0 ]];then 
					sed -i "/$modID/d" "$clusterPath"/"$clusterCode"/Master/modoverrides.lua
					$COLOR && echo "地上世界Mod移除完成" && $RESET
				else
				
					$COLOR && echo "地上世界该Mod不存在" && $RESET
				fi
			else
				echo "该存档没有地上世界"
			fi
			
			if [[ -d $clusterPath/$clusterCode/Caves ]];then
				if [[ $(grep -c "$modID" "$clusterPath"/"$clusterCode"/Caves/modoverrides.lua) -gt 0 ]];then 
					sed -i "/$modID/d" "$clusterPath"/"$clusterCode"/Caves/modoverrides.lua
					$COLOR && echo "地下世界Mod移除完成" && $RESET
				else
					$COLOR && echo "地下世界该Mod不存在" && $RESET
				fi
			else
				$COLOR && echo "该存档没有地下世界" && $RESET
			fi
		esac
	done
	RollBackMain
}

# 添加 Mod
function AddMod()
{
	EchoColor "0" "31"
	local ID1
	local mod3
	local mod4
	
	while :
	do
		echo "============================================"
		echo "请输入要添加的modID ( 返回主菜单输入0 )"
		read -r ID1
		case $ID1 in
			0)break;;
			*)
				if [[ -d $clusterPath/$clusterCode/Master ]];then
				
					if [[ ! -f "${clusterPath}/${clusterCode}/Master/modoverrides.lua" ]];then 
						echo "return {
								}" >> "${clusterPath}/${clusterCode}/Master/modoverrides.lua" 
					fi
					
					if [[  $(grep -c "$ID1" "${clusterPath}/${clusterCode}/Master/modoverrides.lua") -eq 0 ]];then 
						sed -i '$d' "$clusterPath"/"$clusterCode"/Master/modoverrides.lua
						echo "[\"workshop-$ID1\"]={ configuration_options={  }, enabled=true }," >> "$clusterPath"/"$clusterCode"/Master/modoverrides.lua
						echo "}" >> "$clusterPath"/"$clusterCode"/Master/modoverrides.lua
						mod3=1
						$COLOR && echo "地上世界Mod添加完成" && $RESET
					else
						$COLOR && echo "地上世界该Mod已存在" && $RESET
					fi
				else
					$COLOR && echo "该存档没有地上世界" && $RESET
					mod3=0
				fi
				cd "$HOME" || exit 
				if [[ -d $clusterPath/$clusterCode/Caves ]];then
					if [[ $(grep -c "$ID1" "${clusterPath}/${clusterCode}/Caves/modoverrides.lua") -eq 0 ]];then 
						sed -i '$d' "$clusterPath"/"$clusterCode"/Caves/modoverrides.lua
						echo "[\"workshop-$ID1\"]={ configuration_options={  }, enabled=true }," >> "$clusterPath"/"$clusterCode"/Caves/modoverrides.lua
						echo "}" >> "$clusterPath"/"$clusterCode"/Caves/modoverrides.lua
						mod4=$mod3+1
						$COLOR && echo "地下世界Mod添加完成" && $RESET
					else
						$COLOR && echo "地下世界该Mod已存在" && $RESET
					fi
				else
					$COLOR && echo "该存档没有地下世界" && $RESET
					mod4=$mod3+0
				fi
				case $mod4 in
					0)  $COLOR && echo "该存档不存在" && $RESET
					;;
					*)
					;;
				esac
		esac
	done
	RollBackMain
}

# Mod 管理
function ModManage()
{
	EchoColor "0" "31"
	local clusterCode
	local mod1
	local isVer
	local cNameArray
	local cNameId
	
	echo "请输入要管理的版本 [1] 正式版本 [2] 公测版本"
	read -r isVer
	case $isVer in
		1) clusterPath=$clusterPathNormal ;;
		2) clusterPath=$clusterPathBeta ;;
		*) clear ; echo "输入错误，请重新输入！" ;  ModManage ;;
	esac
	
	echo "============================================"
	echo "存档目录"
	cd "$HOME" || exit
	cNameArray=$(ls -l "$clusterPath" | awk '/^d/ {print $NF}' | awk '{print NR,$NF}')
	echo -e "\033[33m$cNameArray \033[0m"
	echo "请输入要管理的存档序号"
	read -r cNameId
	if [[ $( ls -l "$clusterPath" | awk '/^d/ {print $NF}' | wc -l ) -ge $cNameId && $cNameId -ne 0 ]];then
		clusterCode=$(echo "$cNameArray" | awk NR=="$cNameId"'{print $2}')
	else
		ModManage
	fi
	
	while :
	do
	echo "====================================================================="
	echo "[1]添加模组 [2]移除模组 [3]更新模组 [4]清空模组（慎用）[0] 返回主菜单"
	read -r mod1
	case $mod1 in
		0)Main
		break;;
		1)AddMod
		break;;
		2)RemMod
		break;;
		3)UpdateMod
		break;;
		4)echo "请再次输入要清空Mod的存档代码"
		  read -r clusterCode
		  if [[ -d $clusterPath/$clusterCode/Master ]];then 
			echo "return {
				}" > "$clusterPath"/"$clusterCode"/Master/modoverrides.lua
		  fi
		  if [[ -d $clusterPath/$clusterCode/Caves ]];then 
			echo "return {
				}" > "$clusterPath"/"$clusterCode"/Caves/modoverrides.lua
		  fi
		  $COLOR && echo "Mod已清空" && $RESET
		break;;
	esac	
	done
}

# 存档文件释放函数
function ReleaseFileCluster()
{
	EchoColor "0" "31"
	local isVer
	local fNameArray
	local fNameId
	
	echo "请输入要管理的版本 [1] 正式版本 [2] 公测版本"
	read -r isVer
	case $isVer in
		1) clusterPath=$clusterPathNormal ;;
		2) clusterPath=$clusterPathBeta ;;
		*) clear ; $COLOR && echo "输入错误，请重新输入！" && $RESET ;  RecoveryCluster ;;
	esac
	
	fNameArray=$( ls -l "$clusterPath" | awk '/.zip|.tar.gz/ {print $NF}' | cut -d '/' -f2 | awk '{print NR,$NF}' )
	echo "==========================================================="
	$COLOR && echo "备份存档文件 | 如存档已存在，此操作将覆盖存档！（请谨慎对待）" && $RESET
	echo -e "\033[33m$fNameArray \033[0m"
	echo "请输入要释放的存档文件序号"
	read -r fNameId
	if [[ $( ls -l "$clusterPath" | awk '/tar.gz/ {print $NF}' | wc -l ) -ge $fNameId && $fNameId -ne 0 ]];then
		fName=$(echo "$fNameArray" | awk NR=="$fNameId"'{print $2}')
	else
		FileManage
	fi
	
	cd "$clusterPath" || exit
	
	if [[ $(echo "$fName" | cut -d. -f2,3) == "tar.gz" ]];then
		tar -zxf "$fName"
	elif [[ $(echo "$fName" | cut -d. -f2,3) == "zip" || $(echo "$fName" | cut -d. -f2,3) == "ZIP" || $(echo "$fName" | cut -d. -f2,3) == "Zip" ]];then
		unzip -q "$fName"
	fi
	
	$COLOR && echo "存档已释放！" && $RESET
	
	cd "$HOME" || exit
	
	FileManage
}

# 存档删除
function DeleteCluster()
{
	EchoColor "0" "31"
	local clusterCode
	local delbackup1
	
	local isVer
	local cNameId
	local cNameArray
	
	echo "请输入要管理的版本 [1] 正式版本 [2] 公测版本"
	read -r isVer
	case $isVer in
		1) clusterPath=$clusterPathNormal ;;
		2) clusterPath=$clusterPathBeta ;;
		*) clear ; $COLOR && echo "输入错误，请重新输入！" && $RESET ;  RecoveryCluster ;;
	esac

	echo "============================================"
	echo "存档目录"
	cNameArray=$(ls -l "$clusterPath" | awk '/^d/ {print $NF}' | awk '{print NR,$NF}')
	echo -e "\033[33m$cNameArray \033[0m"
	echo "请输入要删除的存档序号"
	read -r cNameId
	if [[ $( ls -l "$clusterPath" | awk '/^d/ {print $NF}' | wc -l ) -ge $cNameId && $cNameId -ne 0 ]];then
		clusterCode=$(echo "$cNameArray" | awk NR=="$cNameId"'{print $2}')
	else
		FileManage
	fi

	cd "$clusterPath" || exit
	if [[ -d $clusterCode ]];then
	rm -r "$clusterCode"
	fi
	
	$COLOR && echo "存档已删除" && $RESET
	if [[ -f "${clusterCode}.tar.gz" ]];then
		echo "是否删除备份？[y/n]"
		read -r delbackup1
			case $delbackup1 in
				1)rm "${clusterCode}".tar.gz
				$COLOR && echo "备份已删除" && $RESET
				;;
				2)
				;;
			esac
	fi
	cd "$HOME" || exit
	FileManage
}

# 存档恢复
function RecoveryCluster()
{
	EchoColor "0" "31"
	local clusterCode
	local isVer
	local cNameId
	local cNameArray
	
	echo "请输入要管理的版本 [1] 正式版本 [2] 公测版本"
	read -r isVer
	case $isVer in
		1) clusterPath=$clusterPathNormal ;;
		2) clusterPath=$clusterPathBeta ;;
		*) clear ; $COLOR && echo "输入错误，请重新输入！" && $RESET ;  RecoveryCluster ;;
	esac
	
	echo "============================================"
	echo "存档目录"
	cNameArray=$(ls -l "$clusterPath" | awk '/^d/ {print $NF}' | awk '{print NR,$NF}')
	echo -e "\033[33m$cNameArray \033[0m"
	echo "请输入要恢复的存档序号"
	read -r cNameId
	if [[ $( ls -l "$clusterPath" | awk '/^d/ {print $NF}' | wc -l ) -ge $cNameId && $cNameId -ne 0 ]];then
		clusterCode=$(echo "$cNameArray" | awk NR=="$cNameId"'{print $2}')
	else
		FileManage
	fi
	
	cd "$clusterPath" || exit
	if [[ -f "${clusterCode}.tar.gz" ]];then
		$COLOR && echo "存档已找到，正在恢复！" && $RESET
		if [[ -d "$clusterCode" ]];then
			rm -r "$clusterCode"
		fi
		tar -zxf "${clusterCode}".tar.gz "$clusterCode"
		$COLOR && echo "存档已恢复！" && $RESET
	else
		$COLOR && echo "备份存档未找到！" && $RESET
	fi
	cd "$HOME" || exit
	FileManage
        
}

# 存档备份
function BackupCluster()
{
	EchoColor "0" "31"
	local clusterCode
	local backup2
	local isVer
	local cNameId
	local cNameArray
	
	echo "请输入要管理的版本 [1] 正式版本 [2] 公测版本"
	read -r isVer
	case $isVer in
		1) clusterPath=$clusterPathNormal ;;
		2) clusterPath=$clusterPathBeta ;;
		*) clear ; $COLOR && echo "输入错误，请重新输入！" && $RESET ;  BackupCluster ;;
	esac
	
	echo "============================================"
	echo "存档目录"
	cNameArray=$(ls -l "$clusterPath" | awk '/^d/ {print $NF}' | awk '{print NR,$NF}')
	echo -e "\033[33m$cNameArray \033[0m"
	echo "请输入要管理的存档序号"
	read -r cNameId
	if [[ $( ls -l "$clusterPath" | awk '/^d/ {print $NF}' | wc -l ) -ge $cNameId && $cNameId -ne 0 ]];then
		clusterCode=$( echo "$cNameArray" | awk NR=="$cNameId"'{print $2}')
	else
		FileManage
	fi
	
	cd "$clusterPath" || exit
	if [[ -d "$clusterCode" ]];then
		if [[ ! -f "${clusterCode}.tar.gz" ]];then
			tar -zcf "${clusterCode}".tar.gz "$clusterCode"
			$COLOR && echo  "备份成功" && $RESET
		else
			echo "备份已存在，是否覆盖？[y/n]"
			read -r backup2
			case $backup2 in
				y)tar -zcf "${clusterCode}".tar.gz "$clusterCode"
				  $COLOR && echo  "备份成功" && $RESET
				  cd "$HOME" || exit
				  FileManage
				;;
				n)cd "$HOME" || exit
				  FileManage
			esac
		fi
	fi
	cd "$HOME" || exit
	FileManage
}

# 存档管理
function FileManage()
{
	local filemanage1
	
	echo "=================================================================="
	echo "[1]备份存档 [2]恢复存档 [3]删除存档 [4]释放备份文件 [0] 返回主菜单"
	read -r filemanage1
		case $filemanage1 in
			0)Main
			;;
			1)BackupCluster
			;;
			2)RecoveryCluster
			;;
			3)DeleteCluster
			;;
			4)ReleaseFileCluster
			;;
			*)echo "指令无效";FileManage
		esac

}

# 启动地下世界
function StartCaves()
{
echo "#!/bin/bash

gamesPath=\"$gamePath/bin$modeBitPath\"
cd \"\$gamesPath\"

run_shared=(./dontstarve_dedicated_server_nullrenderer$modeBit)

# start caves
run_shared+=(-console)

run_shared+=(-persistent_storage_root  $gameApp/klei)

# 忽略更新服务器模组
#run_shared+=(-skip_update_server_mods)

run_shared+=(-cluster $clusterCode)
run_shared+=(-ugc_directory $gameApp/V2Mods)
run_shared+=(-monitor_parent_process $)

\"\${run_shared[@]}\" -shard Caves" > "$clusterPath"/"$clusterCode"/startcaves.sh
	cd "$clusterPath"/"$clusterCode" || exit
	chmod u+x ./startcaves.sh
	cd "$HOME" || exit
	ConfFile
	if [[ $modeBitPath == "64" ]];then
		bitTmp=$modeBitPath
	else
		bitTmp="32"
	fi
	screen -dmS "Caves.$(cat < "$clusterPath"/"$clusterCode"/cluster.ini | grep "cluster_name" | awk '{print $3}').$bitTmp.$gameVersion.$clusterCode." "$clusterPath/$clusterCode/startcaves.sh"
}

# 启动主世界
function StartMaster()
{
echo "#!/bin/bash

gamesPath=\"$gamePath/bin$modeBitPath\"
cd \"\$gamesPath\"

run_shared=(./dontstarve_dedicated_server_nullrenderer$modeBit)

# start Master
run_shared+=(-console)

run_shared+=(-persistent_storage_root $gameApp/klei)
# 忽略更新服务器模组
#run_shared+=(-skip_update_server_mods)

run_shared+=(-cluster $clusterCode)
run_shared+=(-ugc_directory $gameApp/V2Mods)
run_shared+=(-monitor_parent_process $)

\"\${run_shared[@]}\" -shard Master" > "$clusterPath"/"$clusterCode"/startmaster.sh
	cd "$clusterPath"/"$clusterCode" || exit
	chmod u+x ./startmaster.sh
	cd "$HOME" || exit	
	if [[ $modeBitPath == "64" ]];then
		bitTmp=$modeBitPath
	else
		bitTmp="32"
	fi
	screen -dmS "Master.$(cat < "$clusterPath"/"$clusterCode"/cluster.ini | grep "cluster_name" | awk '{print $3}').$bitTmp.$gameVersion.$clusterCode." "$clusterPath/$clusterCode/startmaster.sh"
}

# 创建从服务器世界配置文件
function CreatSlaveCluster()
{
	local gamemode1
	local players
	local ifpvp
	local ifpause
	local intention
	local console
	local token
	local servername
	local description
	local password
	local masterip
	
	
	
	while :
	do
	echo "请选择模式: 1.无尽 2.生存 3.荒野"
	read -r gamemode1
	case $gamemode1 in
		1)
		gamemode1="endless"
		break;;
		2)
		gamemode1="survival"
		break;;
		3)
		gamemode1="wilderness"
		break;;
	esac
	done

	echo "请输入最大玩家数量："
	read -r players

	while :
	do
	echo "是否开启pvp? [y/n]"
	read -r ifpvp
	case $ifpvp in
		y)
		ifpvp="true"
		break;;
		n)
		ifpvp="false"
		break;;
	esac
	done

	while :
	do
	echo "是否开启暂停？[y/n]"
	read -r ifpause
	case $ifpause in
		y)
		ifpause1="true"
		break;;
		n)
		ifpause1="false"
		break;;
	esac
	done

	while :
	do
	echo "请选择游戏难度： 1.休闲 2.合作 3.竞赛 4.疯狂"
	read -r intention
	case $intention in
		1)
		intention1=social
		break;;
		2)
		intention1=cooperative
		break;;
		3)
		intention1=competitive
		break;;
		4)
		intention1=madness
		break;;
	esac
	done

	while :
	do
	echo "控制台是否打开？[y/n]"
	read -r console
	case $console in
		y)
		console1="true"
		break;;
		n)
		console1="false"
		break;;
	esac
	done
	echo "请输入你的饥荒令牌："
	read -r token
	if [[ -z $token || $token = "" ]];then
		EchoColor "0" "44"
		$COLOR && echo "输入令牌为空已添加作者令牌" && $RESET
		
		token="pds-g^KU_iC59_53i^+AGkfKRdMm8uq3FSa08/76lKK1YA8r0qM0iMoIb6Xx4="
	fi

	echo "$token" > "$clusterPath"/"$clusterCode"/cluster_token.txt

	echo "请输入服务器名字："
	read -r servername

	echo "请输入服务器介绍： PS: 若无请按Enter键"
	read -r description

	echo "请输入服务器密码: PS: 若无请按Enter键"
	read -r password

	echo "请输入地上世界服务器外网IP:"
	read -r masterip

echo "[GAMEPLAY]
game_mode = $gamemode1
max_players = $players
pvp = $ifpvp
pause_when_empty = $ifpause1


[NETWORK]
cluster_description = $description
cluster_name = $servername
cluster_intention = $intention1
cluster_password = $password


[MISC]
console_enabled = $console1


[SHARD]
shard_enabled = true
bind_ip = 0.0.0.0
master_ip = $masterip
master_port = 10889
cluster_key = supersecretkey" > "$clusterPath"/"$clusterCode"/cluster.ini
	clear
	echo "服务器配置完成！"
}

# 创建主服务器世界配置文件
function CreatMasterCluster()
{
	local gamemode1
	local players
	local ifpvp
	local ifpause
	local intention
	local console
	local servername
	local description
	local password
	
	while :
	do
	echo "请选择模式: 1.无尽 2.生存 3.荒野"
	read -r gamemode
	case $gamemode in
		1)
		gamemode1="endless"
		break;;
		2)
		gamemode1="survival"
		break;;
		3)
		gamemode1="wilderness"
		break;;
	esac
	done

	echo "请输入最大玩家数量："
	read -r players

	while :
	do
	echo "是否开启pvp？[y/n]"
	read -r ifpvp
	case $ifpvp in
		y)
		ifpvp="true"
		break;;
		n)
		ifpvp="false"
		break;;
	esac
	done

	while :
	do
	echo "是否开启暂停？[y/n]"
	read -r ifpause
	case $ifpause in
		y)
		ifpause1="true"
		break;;
		n)
		ifpause1="false"
		break;;
	esac
	done

	while :
	do
	echo "请选择游戏难度: 1.休闲 2.合作 3.竞赛 4.疯狂"
	read -r intention
	case $intention in
		1)
		intention1=social
		break;;
		2)
		intention1=cooperative
		break;;
		3)
		intention1=competitive
		break;;
		4)
		intention1=madness
		break;;
	esac
	done

	while :
	do
	echo "控制台是否打开？[y/n]"
	read -r console
	case $console in
		y)
		console1="true"
		break;;
		n)
		console1="false"
		break;;
	esac
	done
	
	echo "请输入你的饥荒令牌："
	read -r token
	if [[ -z $token || $token = "" ]];then
		EchoColor "0" "44"
		$COLOR && echo "输入令牌为空已添加作者令牌" && $RESET
		
		token="pds-g^KU_ItJcELlQ^FG2AkgkV+ZGcyvG/KDzkHQgq4/9XhfcjTrVOJA3WhDA="
	fi

	echo "$token" > "$clusterPath"/"$clusterCode"/cluster_token.txt

	echo "请输入服务器名字："
	read -r servername

	echo "请输入服务器介绍: PS: 若无请按Enter键"
	read -r description

	echo "请输入服务器密码: PS: 若无请按Enter键"
	read -r password

echo "[STEAM]
steam_group_admins = true
steam_group_id = 30690547
steam_group_only = false

[GAMEPLAY]
game_mode = $gamemode1
max_players = $players
pvp = $ifpvp
pause_when_empty = $ifpause1


[NETWORK]
cluster_description = $description
cluster_name = $servername
cluster_intention = $intention1
cluster_password = $password


[MISC]
console_enabled = $console1
max_snapshots = 40


[SHARD]
shard_enabled = true
bind_ip = 0.0.0.0
master_ip = 127.0.0.1
master_port = 11111
cluster_key = supersecretkey" > "$clusterPath"/"$clusterCode"/cluster.ini
	clear
	echo "服务器配置完成！"
}

# 创建地下世界配置文件
function CreatCavesini()
{
	echo "[NETWORK]
	server_port = 11101


	[SHARD]
	is_master = false
	name = Caves


	[STEAM]
	master_server_port = 27019
	authentication_port = 8769" > "$clusterPath"/"$clusterCode"/Caves/server.ini
	echo "return {
	override_enabled = true,
	preset = \"DST_CAVE\",
	}" > "$clusterPath"/"$clusterCode"/Caves/worldgenoverride.lua
	echo "return {
	}" >> "$clusterPath/$clusterCode/Caves/modoverrides.lua"
}

# 创建主世界配置文件
function CreatMasterini()
{
	echo "[NETWORK]
	server_port = 11100

	[SHARD]
	is_master = true

	[STEAM]
	master_server_port = 27018
	authentication_port = 8768" > "$clusterPath"/"$clusterCode"/Master/server.ini
	echo "return {
	}" >> "$clusterPath/$clusterCode/Master/modoverrides.lua"
}

# 创建地下世界文件结构
function CavesFile()
{
	echo "============================================"
	echo "请输入存档代码"
	read -r clusterCode
	if [[ ! -d "$HOME/SteamGameApp/klei/DoNotStarveTogether/$clusterCode" ]]
	then 
		mkdir -p "$clusterPath"/"$clusterCode"/Caves
	fi
	CreatCavesini
	CreatSlaveCluster
	StartCaves
}

# 创建主世界文件结构
function MasterFile()
{
	echo "============================================"
	echo "请输入存档代码"
	read -r clusterCode
	if [[ ! -d "$HOME/SteamGameApp/klei/DoNotStarveTogether/$clusterCode" ]]
	then 
		mkdir -p "$clusterPath"/"$clusterCode"/Master
	fi
	CreatMasterini
	CreatSlaveCluster
	StartMaster
}

# 创建世界
function MasterCaves()
{
	local masterCaves1
	
	echo "============================================"
	while :
	do
	echo "[1]地上 [2]地下"
	read -r masterCaves1
	case $masterCaves1 in
		1)MasterFile
		break;;
		2)CavesFile
		break;;
	esac
	done
}

# 判断存档文件
function FileChose()
{ 
	local token_yes
	local token_no
	local zzz
	local zz
	local newfile1
	
	
	if [[ -d "${clusterPath}/$clusterCode" ]];then
		if [[ "$( screen -ls | grep -P 'Master|Caves' | grep -c "$clusterCode" )" -gt 1 ]];then
			clear
			EchoColor "0" "31"
			$COLOR && echo "该服务器已开启该存档地上和地下服务器,请先关闭再启动！！" && $RESET
			RollBackMain
		elif [[ "$(screen -ls | grep Caves | grep -c "$clusterCode")" -gt 0 ]];then
			clear
			echo "该服务器已开启地下服务器,请先关闭再启动！！"
			RollBackMain
		elif [[ "$(screen -ls | grep Master | grep -c "$clusterCode")" -gt 0 ]];then
			clear
			echo "该服务器已开启地上服务器,请先关闭再启动！！"
			RollBackMain
		else 
			
			# 判断是否有token文件
			if [[  -e "$clusterPath/$clusterCode/cluster_token.txt"  ]]; then
				if [[ $(cat < "$clusterPath"/"$clusterCode"/cluster_token.txt | grep -c pds-g^KU ) -eq 0 ]];then
					while [[ $(cat < "$clusterPath"/"$clusterCode"/cluster_token.txt | grep -c pds-g^KU ) -eq 0 ]];do
						echo "该存档token文件无效,是否自动添加作者的token"
						echo "请输入 [Y/y] 同意 或者 [N/n] 拒绝并自己提供一个"
						read -r token_yes
						if [ "$token_yes" == "Y" ] ||  [ "$token_yes" == "y" ]; then
							echo "pds-g^KU_ItJcELlQ^FG2AkgkV+ZGcyvG/KDzkHQgq4/9XhfcjTrVOJA3WhDA=" > "${clusterPath}/${clusterCode}/cluster_token.txt"
						elif [ "$token_yes" == "N" ] ||  [ "$token_yes" == "n" ]; then
							echo "请输入你的 token: "
							read -r token_no
							echo "$token_no" > "${clusterPath}/${clusterCode}/cluster_token.txt"
						else 
							echo "输入有误,请重新输入！！！"
						fi
					done
				fi
				
			else
			
				while [[ ! -e "$clusterPath/$clusterCode/cluster_token.txt" ]];do
					echo "该存档没有token文件,是否自动添加作者的token"
					echo "请输入 [Y/y] 同意 或者 [N/n] 拒绝并自己提供一个"
					read -r token_yes
					if [ "$token_yes" == "Y" ] ||  [ "$token_yes" == "y" ]; then
						echo "pds-g^KU_ItJcELlQ^FG2AkgkV+ZGcyvG/KDzkHQgq4/9XhfcjTrVOJA3WhDA=" > "${clusterPath}/${clusterCode}/cluster_token.txt"
					elif [ "$token_yes" == "N" ] ||  [ "$token_yes" == "n" ]; then
						echo "请输入你的 token: "
						read -r token_no
						echo "$token_no" > "${clusterPath}/${clusterCode}/cluster_token.txt"
					else 
						echo "输入有误,请重新输入！！！"
					fi
				done
			fi
			
			# 存档结构检测
			if [[  -d "$clusterPath/$clusterCode/Master" ]]; then
				zzz=1
			else
				zzz=0
			fi
			if [[ -d "$clusterPath/$clusterCode/Caves" ]] ; then
				zz=$(($zzz+2))
			else
				zz=$(($zzz+4))
			fi
			case $zz in
					2)AddAutoUpdateMod;StartCaves
					;;
					3)AddAutoUpdateMod;StartMaster;StartCaves
					;;
					4)echo "存档没有内容，是否新建？[y/n]"
					  read -r newfile1
					  case $newfile1 in
						y)ModeChose
						;;
						n)Main
					  esac
					;;
					5)AddAutoUpdateMod;StartMaster
					;;
			esac

		fi
	fi
	
	clear
	EchoColor "0" "31"
	$COLOR && echo "操作成功，请耐心等待！" && $RESET
	{
		if [[ -d "${clusterPath}/${clusterCode}/Master" ]];then
			StartCheck "$clusterPath" "$clusterCode" "Master"
		fi
	}&
	{
		if [[ -d "${clusterPath}/${clusterCode}/Caves" ]];then
			StartCheck "$clusterPath" "$clusterCode" "Caves"
		fi
	}&
	wait
	RollBackMain 
}


# 创建世界目录
function NewFile()
{ 
	mkdir -p "$clusterPath"/"$clusterCode"/Master
	mkdir -p "$clusterPath"/"$clusterCode"/Caves
	CreatMasterCluster
	CreatMasterini
	CreatCavesini
	StartMaster
	StartCaves
	RollBackMain 
}

# 关闭服务器
function CloseServer()
{
	local wName1
	local pid1
	local wName11
	local id
	local pid
	local world
	local bit
	local ver
	local cluster
	local status
	local time1
	local cNameArrayNormal
	local cNameNormal
	local cNameArrayBeta
	local cNameBeta
	
	clear
	# 0 正常关服 1 一键关服
	if [[ "$1" -eq 0 ]];then
		
		id=$(screen -ls | grep -c -P 'Master|Caves')
		wName1=""
		for i in $(seq "$id")
			do 	
				wName11=$(screen -ls | grep -P 'Master|Caves' | cut -d '.' -f3 | awk NR=="$i"'{print $0}')
				
				pid=$(screen -ls | grep -P 'Master|Caves' | awk '{print $1}' | cut -d '.' -f1 | awk NR=="$i"'{print $0}')
				world=$(screen -ls | grep -P 'Master|Caves' | cut -d '.' -f2 | awk NR=="$i"'{print $0}')
				bit=$(screen -ls | grep -P 'Master|Caves' |cut -d '.' -f4 | awk NR=="$i"'{print $0}')
				ver=$(screen -ls | grep -P 'Master|Caves' | cut -d '.' -f5 | awk NR=="$i"'{print $0}')
				cluster=$(screen -ls | grep -P 'Master|Caves' | cut -d '.' -f6 | awk NR=="$i"'{print $0}')
				if [[ $os == Debian || $os == Ubuntu ]];then
				status=$(screen -ls | grep -P 'Master|Caves' | cut -d '(' -f3 | cut -d ')' -f1 | awk NR=="$i"'{print $0}')
				time1=$(screen -ls | grep -P 'Master|Caves' | cut -d '(' -f2 | cut -d ')' -f1 | awk NR=="$i"'{print $0}')
				fi
				
				if [[ $os == CentOS ]];then
					status=$(screen -ls | grep -P 'Master|Caves' | cut -d '(' -f2 | cut -d ')' -f1 | awk NR=="$i"'{print $0}')
					time1="系统不支持显示！！！	"
					
				fi
				
				if [[  $wName1 == "" ]];then
						wName1="未获取到世界名称"
				fi
					
				if [[ -z $wName1 || "$wName1" != "$wName11" ]];then
					
					wName1=$wName11
					
					

					echo ""
					echo "=================================================================================================="
					echo "|		世界名称: $wName1									 |"
					echo "=================================================================================================="
					echo -e "| \033[32m$(printf "%-12s %-7s %-5s %-10s %-17s %-10s %-28s\n" PID World Bit Version Cluster Status Time)\033[0m|" 
					echo "--------------------------------------------------------------------------------------------------"

					wName1="$wName11"
				fi

				echo -e "| \033[37m$(printf "%-12s %-7s %-5s %-10s %-17s %-10s %-28s\n" "$pid" "$world" "$bit" "$ver" "$cluster" "$status" "$time1")\033[0m |"
				if [ "$id" -gt "$i" ];then
				echo "--------------------------------------------------------------------------------------------------" 
				fi
				
			done 
		echo "=================================================================================================="
		echo "直接回车返回主目录"
		echo "输入要切换的PID"
		echo "PS:回车后会进入地上或地下的运行界面"
		echo "   手动输入c_shutdown(true)回车保存退出"
		echo "   进入后不想关闭请按ctrl+a+d"

		read -r pid1
		# '^M'
		
		if [[ $pid1 == '^M'  || -z "$pid1" || "$(screen -ls | grep  -P 'Master|Caves' | sed s'/\./ /g' | awk '{print $1}'  | grep -c "$pid1")" -eq 0 ]];then
			RollBackMain clear
		elif [[ "$(screen -ls | grep  -P 'Master|Caves' | sed s'/\./ /g' | awk '{print $1}'  | grep -c "$pid1")" -eq 1 ]];then
			screen -r "$pid1"		
			CloseServer 0
		else
			clear
			echo 
			echo "--------------------------------------------------"
			echo "| PID 输入错误,请重新输入！返回主菜单请按回车！  |"
			echo "--------------------------------------------------"
			CloseServer 0
		fi
		
	elif [[ "$1" -eq 1 ]];then
		EchoColor "0" "31"
		$COLOR && echo "正在关闭服务器~" && $RESET
		# 正式版本进程
		if [[ $(screen -ls | grep -P 'Master|Caves' | grep -c 'Normal') -gt 0 ]];then
			# 正式版本存档长度
			cNameArrayNormal=$(screen -ls | grep -P 'Master|Caves' | sed s'/\./ /g' | grep 'Normal' | awk '{print $6}' | sort -u | wc -l)
			
			for i in $(seq "$cNameArrayNormal" ) 
			do
				# 获取存档名称
				cNameNormal=$(screen -ls | grep -P 'Master|Caves' | sed s'/\./ /g' | grep 'Normal' | awk '{print $6}' | sort -u | awk NR=="$i"'{print $0}')
				
				# 存档结构检测
				if [[ -d "$clusterPathNormal"/"$cNameNormal"/Master || -d "$clusterPathNormal"/"$cNameNormal"/Master && -d "$clusterPathNormal"/"$cNameNormal"/Caves ]];then
					
					# 进程获取
					MasterProcess Normal "$cNameNormal" Master
					
					# 玩家人数显示
					GamePlayersList "$masterProcess" Normal "$cNameNormal" Master

				elif [[ -d "$clusterPathNormal"/"$cNameNormal"/Caves ]];then
				
					# 进程获取
					MasterProcess Normal "$cNameNormal" Caves
					# 玩家人数显示
					GamePlayersList "$masterProcess" Normal "$cNameNormal" Caves

				fi
				
				# 检测存档是否存在玩家
				if [[ $gamePlayerListFlag == 1 ]];then
					echo "[ $cNameNormal ]存档存在玩家是否继续关闭 [y/n]"
					read -r temp2
					if [[ $temp2 == "y" ]];then
						# 发布存档世界公告
						GameAnnounce "$masterProcess" "世界正在进行存档！"
						GameSave "$masterProcess"
						sleep 2s
						
						# 发布关闭世界公告
						GameAnnounce "$masterProcess" "世界即将在3秒后关闭!"
						sleep 2s
						GameAnnounce "$masterProcess" "世界即将关闭!"
						sleep 1.5s
						GameAnnounce "$masterProcess" "世界即将关闭!"
						sleep 1.5s
						GameAnnounce "$masterProcess" "世界即将关闭!"
						sleep 1.5s
						# 关闭当前服务器
						screen -ls | grep -P 'Master|Caves' | grep "$cNameNormal" | cut -d. -f1 | awk '{print $1}' | xargs kill > /dev/null 2>&1 &
					elif [[ $temp2 == "n" ]];then
						continue
					else
						echo "输入有误，返回主菜单！"
						RollBackMain
					fi
				# 没有人直接关闭该存档
				elif [[ $gamePlayerListFlag == 0 ]];then

					GameSave "$masterProcess"
					sleep 2s
					# 关闭当前服务器
					screen -ls | grep -P 'Master|Caves' | grep "$cNameNormal" | cut -d. -f1 | awk '{print $1}' | xargs kill > /dev/null 2>&1 &
				fi
				

			done
		fi
		
		# 公测版本进程
		if [[ $(screen -ls | grep -P 'Master|Caves' | grep -c 'Beta') -gt 0 ]];then
		 # 公测版本存档名称数组
			cNameArrayBeta=$(screen -ls | grep -P 'Master|Caves' | sed s'/\./ /g' | grep 'Beta' | awk '{print $6}' | sort -u | wc -l)
			
			for i in $(seq "$cNameArrayBeta" ) 
			do
				# 获取存档名称
				cNameBeta=$(screen -ls | grep -P 'Master|Caves' | sed s'/\./ /g' | grep 'Beta' | awk '{print $6}' | sort -u | awk NR=="$i"'{print $0}')
				# 存档结构检测
				if [[ -d "$clusterPathNormal"/"$cNameNormal"/Master || -d "$clusterPathBeta"/"$cNameBeta"/Master && -d "$clusterPathBeta"/"$cNameBeta"/Caves ]];then
					
					# 进程获取
					MasterProcess Beta "$cNameBeta" Master
					# 玩家人数显示
					GamePlayersList "$masterProcess" Beta "$cNameBeta" Master

				elif [[ -d "$clusterPathBeta"/"$cNameBeta"/Caves ]];then
				
					# 进程获取
					MasterProcess Beta "$cNameBeta" Caves
					# 玩家人数显示
					GamePlayersList "$masterProcess" Beta "$cNameBeta" Caves
					
				echo
				fi
				
				if [[ $gamePlayerListFlag == 1 ]];then
					echo "[ $cNameBeta ]存档存在玩家是否继续关闭 [y/n]"
					read -r temp3
					if [[ $temp3 == "y" ]];then
						# 发布存档世界公告
						GameAnnounce "$masterProcess" "世界正在进行存档！"
						GameSave "$masterProcess"
						sleep 2s
						
						# 发布关闭世界公告
						GameAnnounce "$masterProcess" "世界即将在3秒后关闭！"
						sleep 2s
						GameAnnounce "$masterProcess" "世界即将关闭！"
						sleep 1.5s
						GameAnnounce "$masterProcess" "世界即将关闭！"
						sleep 1.5s
						GameAnnounce "$masterProcess" "世界即将关闭！"
						sleep 1.5s
						# 关闭当前服务器
						screen -ls | grep -P 'Master|Caves' | grep "$cNameBeta" | cut -d. -f1 | awk '{print $1}' | xargs kill > /dev/null 2>&1 &
					elif [[ $temp3 == "n" ]];then
						continue
					else
						echo "输入有误，返回主菜单！"
						RollBackMain
					fi
				# 没有人直接关闭该存档
				elif [[ $gamePlayerListFlag == 0 ]];then

					GameSave "$masterProcess"
					sleep 2s
					# 关闭当前服务器
					screen -ls | grep -P 'Master|Caves' | grep "$cNameBeta" | cut -d. -f1 | awk '{print $1}' | xargs kill > /dev/null 2>&1 &
				fi
				

			done
		fi
		
		clear
		echo "--------------------"
		echo "| 已关闭相应服务器 |"
		echo "--------------------"
		RollBackMain
	fi

}

# 单双服务器模式选择
function ModeChose()
{
	echo "============================================"
	while :
	do
	echo "[1]单服务器搭建 [2]双服务器搭建 "
	read -r servermode
	case $servermode in
		1)NewFile
		break;;
		2)MasterCaves
		break;;
	esac
	done	
}

# 脚本更新
function UpdateShell()
{	 
	# 手动更新：$1=Manual
		echo "请耐心等待正在检测脚本更新文件，这个过程预计 10s-60s"
		curl -s -o "$HOME"/.dstconf/newshell https://gitee.com/changheqin/dst-server-for-linux-shell/releases
		#重载配置文件
		ConfFile
		# 验证newshell 文件是否存在
		if [[ -f "$HOME"/.dstconf/newshell ]];then
			
			if [[ "$newShellVersion" != "$shellVersion" || $1 == "Manual" ]];then	
				wget -O newgo  https://gitee.com/changheqin/dst-server-for-linux-shell/releases/download/"$newShellVersion"/go.sh
				
				# 验证newgo是否下载成功
				if [[ $(cat < "$HOME"/newgo | grep -c 'shellVersion=') -gt 0 ]];then
				
					chmod +x newgo
					rm -rf go.sh 
					mv newgo go.sh
					clear
					echo "Shell 脚本 更新完毕！请重新运行脚本！"
					echo "Shell 脚本 更新完毕！请重新运行脚本！"
					echo "Shell 脚本 更新完毕！请重新运行脚本！"
					exit 1
					
				else
					echo "脚本更新失败！"
				fi
			fi
		fi		
}

# 服务器更新
function UpdateGame()
{	
	
	# 初次安装不执行检测更新
	if [[ "$isFlag" != 1 ]];then
		RemoteVersion
		ConfFile
		# 完整安装模式
		if [[ $installMode == 0 ]];then
			LocalVersion Normal
			LocalVersion Beta
			if [[ "$remoteNormal" != "$localNormal" ]];then
				InstallGame Normal
			fi

			if [[ "$remoteBeta" != "$localBeta" ]];then
				if [[ $remoteBeta1 -eq 1 ]];then
					InstallGame Beta
				fi
			fi
	
		# 单正式版本模式
		elif [[ $installMode == 1 ]];then
			LocalVersion Normal
			if [[ "$remoteNormal" != "$localNormal" ]];then
				InstallGame Normal
			fi
		# 单公测版模式
		elif [[ $installMode == 2 ]];then
			LocalVersion Beta
			if [[ "$remoteBeta" != "$localBeta" ]];then
				if [[ $remoteBeta1 -eq 1 ]];then
					InstallGame Beta
				fi
			fi
		fi
	fi

}

function RemoteVersion()
{
	cd "$HOME"/.steamcmd || exit
	echo "请耐心等待正在检测游戏更新文件，这个过程预计 10s-60s"
	# 网络检查
	if [[ $(ping baidu.com -c 1 | grep "ttl" | grep -c "ms") -lt 1 ]];then
		EchoColor "0" "31"
		$COLOR && echo "网络故障请检查网络！" && $RESET
		$COLOR && echo "网络故障请检查网络！" && $RESET
		$COLOR && echo "网络故障请检查网络！" && $RESET
		RollBackMain
	fi
	remoteNormal=$( ./steamcmd.sh +login anonymous +app_info_update 1 +app_info_print 343050 +quit | sed -e '/"branches"/,/^}/!d' | sed -n "/\"public\"/,/}/p" | grep -m 1 buildid | tr -cd '[:digit:]')
	remoteBeta=$( ./steamcmd.sh +login anonymous +app_info_update 1 +app_info_print 343050 +quit | sed -e '/"branches"/,/^}/!d' | sed -n "/\"updatebeta\"/,/}/p" | grep -m 1 buildid | tr -cd '[:digit:]')
	if [[ -z $remoteNormal || $remoteNormal == "" ]];then
		echo "远程正式版本:$remoteNormal "
		RemoteVersion
	fi
	
	if [[ -z $remoteBeta || $remoteBeta == "" ]];then
		remoteBeta1=$(./steamcmd.sh +login anonymous +app_info_update 1 +app_info_print 343050 +quit | sed -e '/"branches"/,/^}/!d' | grep -c "updatebeta" )
		if [[ $remoteBeta1 == 1 ]];then
			echo "远程公测版本:$remoteBeta"
			RemoteVersion
		else
			echo "公测版本已被官方关闭"
		fi
		
		

	fi
	cd "$HOME" || exit
}

function LocalVersion()
{
	# $1 = Normal or Beta

	if [[ $1 == Normal || $1 == normal ]];then
		localNormal=$(cat < "$gamePathNormal"/steamapps/appmanifest_343050.acf | grep -m 1 buildid | tr -cd '[:digit:]')
	elif [[ $1 == Beta || $1 == beta ]];then
		localBeta=$(cat < "$gamePathBeta"/steamapps/appmanifest_343050.acf | grep -m 1 buildid | tr -cd '[:digit:]')
	else
		echo "参数给定错误！"
	fi
}

function InstallGame()
{
	# $1 = Normal or Beta 

	cd "$HOME"/.steamcmd || exit

	if [[ $1 == Normal || $1 == normal ]];then 
		echo "即将安装正式版本..."
		#clear
		true > "$HOME"/.dstconf/dst_steamcmd.log
		./steamcmd.sh +force_install_dir "${gamePathNormal}" +login anonymous +app_update 343050 validate +quit | tee "$HOME"/.dstconf/dst_steamcmd.log
		LogCheck "${HOME}/.dstconf/dst_steamcmd.log" "Success! App '343050' fully installed." "Fatal Error: Steamcmd needs to be online to update."
	elif [[ $1 == Beta || $1 == beta  ]];then
		echo "即将安装公测版本..."
		#clear
		true > "$HOME"/.dstconf/dst_beta_steamcmd.log
		./steamcmd.sh +force_install_dir "${gamePathBeta}" +login anonymous +app_update 343050  -beta "${betaKey}"  validate +quit | tee "$HOME"/.dstconf/dst_beta_steamcmd.log
		LogCheck "${HOME}/.dstconf/dst_beta_steamcmd.log" "Success! App '343050' fully installed." "Fatal Error: Steamcmd needs to be online to update."
	else
		echo "参数给定错误，结束执行"
		sleep 1s
		exit 
	fi

	if [[ "$logCheckNum3" -ge 1 ]];then
		echo -e "$(cowsay -f mutilated SteamCMD 网络故障 请重试！)"
		# 给定父进程退出指令
		isFlag=4
		exit
	fi
	# SteamCMD 发生错误再次执行安装任务 
	if [[ "$logCheckNum2" -lt 1 ]];then
		InstallGame "$1"
	fi
}

function LogCheck()
{
	# $1 文件位置	例如：/root/.dstconf/update.log
	# $2 检测内容	例如："test"
	# $3 检测内容	例如："test"
	# 返回数值 logCheckNum=0 代表没有该内容 
	# 返回数值 logCheckString="" 代表没有该内容 

	if [[ -f $1 ]];then
		logCheckNum2=$(cat < "$1" | grep -a -c "$2"  )
		#logCheckString2=$(cat < "$1" | grep -a "$2"  )
		logCheckNum3=$(cat < "$1" | grep -a -c "$3"  )
		#logCheckString3=$(cat < "$1" | grep -a "$3"  )
	else
		echo "被检测文件不存在！"	
	fi

}

# 检测共享库函数
function LibraryCheck()
{
	local gamePath
	echo "请耐心等待正在检测系统共享库文件，这个过程预计 1s-10s"
	if [[ "$installMode" == 2 ]];then
			gamePath=$gamePathBeta
	else
			gamePath=$gamePathNormal
	fi
	# 检测程序是否存在
	if [ -e "$gamePath"/bin/dontstarve_dedicated_server_nullrenderer ];then
		# 检测 32 位程序库是否缺失
		if [[ "$(ldd "$gamePath"/bin/dontstarve_dedicated_server_nullrenderer | grep -c "not found")" -gt 0 || "$(ldd "$gamePathNormal"/bin64/dontstarve_dedicated_server_nullrenderer_x64 | grep -c "not found")" -gt 0 ]];then
			
			
			echo "=============================="
			# 显示缺失的32库
			if [[ $(ldd "$gamePath"/bin/dontstarve_dedicated_server_nullrenderer | grep -c "not found" ) -gt 0 ]];then
			ldd "$gamePath"/bin/dontstarve_dedicated_server_nullrenderer  | grep "not found" | sed s'/\t//g' | sort -u
			fi
			# 显示缺失的64库
			if [[ $(ldd "$gamePath"/bin64/dontstarve_dedicated_server_nullrenderer_x64 | grep -c "not found" ) -gt 0 ]];then
			ldd "$gamePath"/bin64/dontstarve_dedicated_server_nullrenderer_x64 | grep "not found" | sed s'/\t//g' | sort -u
			fi
			echo "=============================="
			echo "游戏程序缺少以上共享库组件！"
			echo "5秒后即将尝试重新安装系统环境!"
			echo "5秒后即将尝试重新安装系统环境!"
			echo "5秒后即将尝试重新安装系统环境!"
			sleep 5s
			
			# 重新安装环境
			Library
		fi

	fi
}

# 配置 系统环境库
function Library()
{
	if [[ "$os" == "Ubuntu" || "$os" == 'Debian' ]];then

		echo ""
		echo "##########################"
		if [[ "$os" == "Debian" ]];then
		 		echo "# 加载 Debian Linux 环境 #"
		fi
		if [[ "$os" == "Ubuntu" ]];then
		 		echo "# 加载 Ubuntu Linux 环境 #"
		fi
		echo "##########################"
		echo ""
		# 开启 32bit 库
		dpkg --add-architecture i386
		apt -y install sudo 
		sudo apt -y update
		sudo apt -y install wget
		sudo apt -y install curl
		sudo apt -y install screen
		sudo apt -y install cowsay
		sudo apt -y install cron
		sudo apt -y install bsdextrautils
		sudo apt -y install iputils-ping

		# 加载 64bit库 必须优先加载64位库 不然会导致32位库被卸载
		sudo apt -y install lib64gcc-s1 lib64stdc++6 libcurl4-gnutls-dev
		 
		# 加载 32bit 库
		sudo apt -y install lib32gcc-s1 lib32stdc++6 libcurl4-gnutls-dev:i386

		if [[ $os == "Debian" ]];then
			ln -s /usr/games/cowsay /usr/bin/
		fi

		if [[ -f "/usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4" ]];then
			ln -sf /usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4 /usr/lib/libcurl-gnutls.so.4
		fi

	elif [[ "$os" == "CentOS" ]];then

		echo ""
		echo "##########################"
		echo "# 加载 CentOS Linux 环境 #"
		echo "##########################"
		echo ""
		sudo yum -y install epel-release
		sudo yum -y update
		sudo yum -y install tar wget screen curl cowsay

		# 加载 32bit 库
		sudo yum -y install glibc.i686 libstdc++.i686 libcurl.i686
		 
		# 加载 64bit 库
		sudo yum -y install glibc libstdc++ libcurl
		 
		if [[ -f "/usr/lib/libcurl.so.4" ]];then
			ln -sf /usr/lib/libcurl.so.4 /usr/lib/libcurl-gnutls.so.4	
		fi
		if [[ -f "/usr/lib64/libcurl.so.4" ]];then
			ln -sf /usr/lib64/libcurl.so.4 /usr/lib64/libcurl-gnutls.so.4
		fi
	elif [[ "$os" == "Arch" ]];then

		echo ""
		echo "########################"
		echo "# 加载 Arch Linux 环境 #"
		echo "########################"
		echo ""


		sudo pacman -Syyy
		sudo pacman -S --noconfirm wget screen curl ping cowsay
		sudo pacman -S --noconfirm lib32-gcc-libs libcurl-gnutls
		 
		 
		 
	else
		EchoColor "0" "35"
		$COLOR && echo "该系统未被本脚本支持！,请联系作者！" && $RESET
		$COLOR && echo "该系统未被本脚本支持！,请联系作者！" && $RESET
		$COLOR && echo "该系统未被本脚本支持！,请联系作者！" && $RESET
		exit
	fi


}

function Setup()
{
	local isFlag
	local dir

	if [[ ! -d "$HOME"/.dstconf ]];then
		mkdir "$HOME"/.dstconf
	fi

	if [[ ! -d "$HOME"/.steamcmd ]];then
		
		# 安装系统相关组件
		Library

		mkdir "$HOME"/.steamcmd
		
		dir=$(cd "$HOME"  && pwd)
		
		if [[ "$os" == "Debian" || "$os" == "Ubuntu" ]];then
		# 添加自动更新命令
			systemctl  enable cron
			echo "*/30 * * * * /bin/bash $dir/go.sh autoupdate > $HOME/.dstconf/crontab.log " >> /var/spool/cron/crontabs/"${USER}"
		fi
		
		if [[ "$os" == "CentOS" ]];then
			echo "*/30 * * * * /bin/bash $dir/go.sh autoupdate > $HOME/.dstconf/crontab.log " >> /var/spool/cron/"${USER}"
		fi
		
		
		cd "$HOME"/.steamcmd || exit
		wget https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz
		tar -xvzf steamcmd_linux.tar.gz
		rm -f steamcmd_linux.tar.gz

		isFlag=1
	fi
	
	# 选择安装版本
	if [[ $isFlag -eq 1 ]];then
		echo -e "请输入要安装的版本：[0]正式版本和公测版本 [1]正式版本 [2]公测版本"
		read -r isMode
		
		if [[ $isMode -eq 0 ]];then
			# 正式版路径
			{
				mkdir "$gamePathNormal" -p
				InstallGame Normal
				
			}&
			# 公测版路径
			{
				mkdir "$gamePathBeta" -p
				InstallGame Beta
			}&
			if [[ $isFlag == 4 ]];then
				# Steam错误 父进程主动退出
				exit	
			fi
			wait
			isFlag=0
		elif [[ $isMode -eq 1 ]];then
			# 正式版路径
			mkdir "$gamePathNormal" -p
			InstallGame Normal
			isFlag=0
		elif [[ $isMode -eq 2 ]];then
			# 公测版路径
			mkdir "$gamePathBeta" -p
			InstallGame Beta
			isFlag=0
		else
			echo "输入有误！"
			isFlag=1
			Setup
			
		fi
		# 创建配置文件
		if [[ -f "$gamePathNormal"/steamapps/appmanifest_343050.acf  ]];then
			# 创建配置文件
			CreatConfigFile
		fi
		if [[ -f "$gamePathBeta"/steamapps/appmanifest_343050.acf ]];then
			# 创建配置文件
			CreatConfigFile
		fi
		
		echo -e "$( cowsay -f vader-koala.cow 安装完毕 | grep -v -P 'Darth|Vader|koala' )"
		sleep 3s
	fi



	if [[ ! -d "$gameApp"/klei/DoNotStarveTogether ]];then
		# 存档路径
		mkdir "$gameApp"/klei/DoNotStarveTogether -p
		mkdir "$gameApp"/klei/DoNotStarveTogetherBetaBranch -p
	fi

	if [[ ! -d "$gameApp"/V2Mods ]];then
		# V2 模组公共文件路径
		mkdir "$gameApp"/V2Mods -p
	fi
}

# 准备
function Prepare()
{
	# 初始化脚本
	Setup
	
	# 检测共享库文件
	LibraryCheck

	
	if [[ $NOT_UPDATE_SHELL != yes ]];then
		# 脚本更新
		UpdateShell
	fi
	
	if [[ $NOT_UPDATE_GAME != yes ]];then
		# 检测更新Game
		UpdateGame
	fi
	
	clear

	# 更新配置
	ConfFile
	
	# 检测更新Mod
	CheckUpdateMod
	
}

# 主程序
function Main()
{
	local note

	ConfFile
	if [[ $installMode == 0 ]];then
		note="完整安装"
	elif [[ $installMode == 1 ]];then
		note="单正式版本"
	elif [[ $installMode == 2 ]];then
		note="单公测版本"
	fi
	
	while :
	do
	echo "===================================================="
	echo " 正式版本：$localVerGame	| 公测版本：$localVerGameBeta"
	echo "===================================================="
	echo "$os Linux 环境 | 作者：小草哥哥 | Ver:$shellVersion"
	echo "----------------------------------------------------"
	echo -e "饥荒联机群: 246489642      \033[33m${note} \033[0m "
	echo "===================================================="
	echo "[1]启动正式服务器	[2]启动公测服务器"
	echo "[3]查看服务器	        [4]快捷关服（有玩家需选择关闭）"
	echo "[5]快捷存档             [6]快捷回档"
	echo "[7]服务器公告           [8]在线人数"
	echo "[9]设置面板"
	echo "[0]退出脚本"
	echo "===================================================="
	echo 
	read -r input
		case $input in
		1)StartServer Normal
		break;;
		2)StartServer Beta
		break;;
		3)CloseServer 0
		break;;
		4)CloseServer 1
		break;;
		5)QuickSave
		break;;
		6)QuickRollBack
		break;;
		7)QuickAnnounce
		break;;
		8)OnlinePlayers
		break;;
		9)ControlPanel
		break;;
		0)clear;exit
		break;;
		00)DiyGameCommand
		esac
		clear
	done
		
}


# 程序入口
while getopts ":unrxh" optname ; do
	case $optname in
		"u")
			EchoColor "0" "31"
			$COLOR && echo "检测到强制更新 Shell 选项！" && $RESET
			sleep 1.5s
			UpdateShell Manual
			
		;;
		"n")
			NOT_UPDATE_GAME="yes"
			NOT_UPDATE_SHELL="yes"
			EchoColor "0" "31"
			$COLOR && echo "检测到忽略更新选项！" && $RESET
			sleep 1.5s
		;;
		"r")
			echo ""
			sudo rm $HOME/.steamcmd/ $HOME/.SteamGameApp/ -rf
			$COLOR && echo "脚本已重置！" && $RESET
			exit 0
		;;
		"x")
			echo ""
			sudo rm $HOME/SteamGameApp/Dst $HOME/SteamGameApp/DstBeta -rf
			echo "游戏已卸载！"
			exit 0
		;;
		"h")
			echo ""
			echo "  go.sh：用法：./go.sh [-optstring] [arg ...]"
			echo ""
			echo "  例如：./go.sh -n "
			echo ""
			echo "  -u 强制更新脚本!"
			echo "  -n 忽略更新服务器，忽略更新脚本！以增加启动速度！ "
			echo "  -r 重置脚本，重新安装!"
			echo "  -x 卸载全部饥荒服务器！"
			echo "  -h help go.sh 帮助!"
			
			exit 0
		;;
		"?")
			echo "Unknown option $OPTARG"
		;;
		":")
			echo "No argument value for option $OPTARG"
		;;
		*)
			echo "Unknown error while processing options"
		;;
	esac

done
echo -e "$( cowsay -p 欢迎使用 )"
Prepare
echo -e "$( cowsay -f vader-koala.cow 准备完毕 | grep -v -P 'Darth|Vader|koala' )"

if [[ $1 == autoupdate ]];then
	exit
fi
Main 
